Review Dijkstra's algorithm and practice my English

/*
Problem description:

in a directed graph with N nodes, starting from node 1 to i (i=2, 3, ..., N) and back to 1,

(assume that going from node 1 to i needs time = weight(node 1, node i))

count the minimum time needed.


Solution:
			calculate the shortest paths from 
			1:	from 1 to i (i=2, 3, ..., n) 
			2:	from i to 1 (i=2, 3, ..., n)
			for 1, just use Dijktra
			for 2, just reverse the graph and transform it into situation 1			
*/

#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;

#define MAX 100011

struct node{										// the node of graph
	int num;										// the number of current node
	int dist;										// the distance of previous node to current node
};
struct cmp{// for maintaining a minimum stack
	bool operator()(node x, node y){
		return x.dist > y.dist ? true : false;
	}
};

priority_queue<node, vector<node>, cmp> myQueue;	// use for dijkstra algorithm to maitain the nodes to be expanded

vector<node> vList01[MAX];	// use linkedlist to store a graph
vector<node> vList02[MAX];	// store a reversed graph

int time = 0;
int dist[MAX];				// dist[i] means the distance from star -> i
int vist[MAX];				// vist[i] means whether No.i node was visted


/*
Dijkstra's algorithm
*/
void dijkstra(vector<node> vList[MAX], int n){
	int i;

	for(i=1; i<=n; i++){	// init flag
		dist[i] = INT_MAX;
		vist[i] = 0;
	}
	
	node start;				// start node
	start.num = 1;
	start.dist = 0;
	dist[1] = 0;
	
	myQueue.push(start);

	while(!myQueue.empty()){// expand until all nodes were added
		node v = myQueue.top();
		myQueue.pop();

		if(vist[v.num] == 1)	continue;
		vist[v.num] = 1;

		int len = vList[v.num].size();
		for(i=0; i<len; i++){
			node next = vList[v.num][i];				// neighbouring nodes

			if(dist[v.num]+next.dist < dist[next.num]){	// relax node
				dist[next.num] = dist[v.num]+next.dist;
				next.dist = dist[next.num];

				myQueue.push(next);// add node to be expand 
			}
		}
	}
	
	for(i=1; i<=n; i++){	// count the time 
		time += dist[i];
		//printf("1->%d = %d\n", i, dist[i]);
	}	
}



int main(){
	int ti, ni, mi;
	int t, n, m;
	
	scanf("%d", &t);
	for(ti=0; ti<t; ti++){
		scanf("%d %d", &n, &m);
		
		for(mi=0; mi<m; mi++){
			int x, y, w;
			scanf("%d %d %d", &x, &y, &w);
			
			// build a normal graph
			node v;
			v.num = y;
			v.dist = w;			
			vList01[x].push_back(v);
			
			// build a reversed graph
			node u;
			u.num = x;
			u.dist = w;
			vList02[y].push_back(u);
		}
		
		// sovle
		time = 0;
		dijkstra(vList01, n);
		dijkstra(vList02, n);
		
		//clear graph
		for(ni=1; ni<=n; ni++){
			vList01[ni].clear();
			vList02[ni].clear();
		}

		printf("%d\n", time);
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章