Review Dijkstra's algorithm and practice my English

本文介绍了一种使用Dijkstra算法计算有向图中从特定节点到所有其他节点的最短路径的方法,并通过反转图来解决从任意节点返回起始节点的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值