题目:http://acm.hdu.edu.cn/showproblem.php?pid=2680
/************************************************************************/ /* hdu Arbitrage dijkstra算法 题目大意:dijkstra算法,求点与点之间最短距离。因为此题的起始点不定,所以可用 反向图来求得,终点确定,从终点出发,dijkstra算法,求出其他点到终点最小距离。 本题数据量较大,用floyd算法超时。 */ /************************************************************************/ #include <cstdio> #include <cstring> #include <string> #include <map> #include <algorithm> using namespace std; #define MIN(a,b) a<b?a:b #define MAX 0xfffffff const int N = 1001; int maps[N][N]; int dj[N],vis[N]; int m,n,s,w,num,min_num; void build_map() { int p,q,t; for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) maps[i][j] = maps[j][i] = ((i==j)?0:MAX); for (int i = 1; i <= m; i++) { scanf("%d%d%d",&p,&q,&t); if(maps[q][p] > t) maps[q][p] = t;//这里注意构建反向图 } for (int i = 1; i <= n; i++) dj[i] = MAX; } /* //此floyd算法超时 void floyud() { for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) maps[i][j] = MIN(maps[i][j],maps[i][k] + maps[k][j]); } } */ void DJ() { int cur = s; int next,min; dj[cur] = 0; while(1) { min = MAX; vis[cur] = 1; for (int i = 1; i <= n; i++) { if (vis[i] == 1)continue; if (dj[i] > dj[cur] + maps[cur][i]) dj[i] = dj[cur] + maps[cur][i]; if (dj[i] < min) { min = dj[i]; next = i; } } if ( min == MAX)break; cur = next; } } int main() { while(scanf("%d%d%d",&n,&m,&s)!= EOF ) { build_map(); memset(vis,0,sizeof(vis)); DJ(); min_num = MAX; scanf("%d",&w); while(w--) { scanf("%d",&num); if ( dj[num] < min_num) min_num = dj[num]; } if (min_num == MAX) printf("-1 "); else printf("%d ",min_num); } return 0; }