Cod sursa(job #492205)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 13 octombrie 2010 19:36:45
Problema Algoritmul Bellman-Ford Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<queue>
#include<cstring>
#define MAXN 50001
#define INF 0x17D7841
using namespace std;

typedef unsigned short uint16;
typedef pair<pair<uint16,uint16>,short> Edge;

struct Compare
{
	const bool operator() (const Edge& a, const Edge& b) const
	{
		return a.second<b.second;
	}
};

void BellmanFord(const vector<vector<Edge> >& edges, 
				 const int n,
				 const int m,
				 const uint16 s,
				 int *dist)
{
	//vector<Edge> heap=edges[s];
	//make_heap(heap[s].begin(),heap[s].end());
	//multiset<int> nodes;
	queue<int> nodes;
	bool passed[MAXN]={false};
	
	memset(dist,0x3f,n*sizeof(int));
	dist[s]=0;
	
	for(int i=0; i<(int)edges[s].size(); ++i)
		//nodes.insert(edges[s][i].first.first);
		nodes.push(edges[s][i].first.first);
	
	/*for(multiset<int> ::iterator it=nodes.begin(); it!=nodes.end(); it++)
	{
		cout<<"Da\n";
		for(int j=0; j<(int)edges[*it].size(); ++j)
		{
			cout<<edges[*it][j].first.first<<" "<<edges[*it][j].first.second<<" "<<edges[*it][j].second<<endl;
			if(dist[edges[*it][j].first.first] + edges[*it][j].second < dist[edges[*it][j].first.second])
			{
				dist[edges[*it][j].first.second]=dist[edges[*it][j].first.first] + edges[*it][j].second;
				nodes.insert(edges[*it][j].first.second);
			}
		}
	}*/
	
	while(!nodes.empty())
	//for(int i=0; i<n-1; ++i)
	{
		const int node=nodes.front();
		nodes.pop();
		for(int j=0; j<(int)edges[node].size(); ++j)
			if(dist[edges[node][j].first.first] + edges[node][j].second < dist[edges[node][j].first.second])
			{
				dist[edges[node][j].first.second]=dist[edges[node][j].first.first] + edges[node][j].second;
				//nodes.insert(edges[node][j].first.second);
				if(!passed[edges[node][j].first.second])
				{
					passed[edges[node][j].first.second]=true;
					nodes.push(edges[node][j].first.second);
				}
			}
	}
}

bool CheckForCycle(vector<vector<Edge> >& edges,
				   const int *dist)
{
	for(vector<vector<Edge> >::iterator it=edges.begin(); it!=edges.end(); it++)
	{
		for(int i=0; i<(int)it->size(); ++i)
			if(dist[(*it)[i].first.first] + (*it)[i].second < dist[(*it)[i].first.second])
				return true;
	}
	return false;
}

int main()
{
	uint16 a,b;
	short c;
	int n,m,dist[MAXN];
	fstream fin("bellmanford.in", fstream::in);
	fstream fout("bellmanford.out", fstream::out);
	
	vector<vector<Edge> > edges;
	
	fin>>n>>m;
	//cout<<n<<" "<<m<<endl;
	edges.resize(n);
	
	for(int i=0; i<m; ++i)
	{
		fin>>a>>b>>c;
		//cout<<a-1<<" "<<b-1<<" "<<c<<endl;
		edges[a-1].push_back(make_pair(make_pair(a-1,b-1),c));
	}
	
	BellmanFord(edges,n,m,0,dist);
	
	if(CheckForCycle(edges,dist))
	{
		fout<<"Ciclu negativ!\n";
	}
	else
	{
		for(int i=1; i<n; ++i)
		{
			fout<<dist[i]<<" ";
		}
	}
	//cout<<endl;
	
	fin.close();
	fout.close();
	return 0;
}