http://acm.hdu.edu.cn/showproblem.php?pid=2066
还是多点dijkstra 这里要注意出发城市和到达城市 有可能不在n m里
例如 n=2, m=3 这只表明有几个城市 但是有可能城市标号为10.
故对于每个case 要计算出一个big,他为出发城市和到达城市 标号最大的
如果标号很大 但是城市个数相对较小 可以使用离散化方法
这题很坑爹 题意应该是单向边 居然是双向的=-=


#include <stdio.h> #include <string.h> #include <queue> using namespace std; const int INF = (1<<30), MAXN = 1005; bool set[MAXN]; int dis[MAXN], n, m, r[MAXN][MAXN], ju[MAXN][MAXN]; int begin[MAXN], end[MAXN], big; void dij(int src) { int i, round, min, pos; for(i=1; i<=big; i++) dis[i] = r[src][i]; memset(set, 0, sizeof(set)); dis[src] = 0; for(round=1; round<=big; round ++) { min = INF, pos = INF; for(i=1; i<=big; i++) { if(!set[i] && min > dis[i]) { min = dis[i], pos = i; } } if( pos == INF ) break; set[pos] = 1; for(i=1; i<=big; i++) { if(!set[i] && dis[i] > r[pos][i] + dis[pos]) dis[i] = r[pos][i] + dis[pos]; } } for(i=1; i<=big; i++) ju[src][i] = dis[i]; } int minF(int a, int b) { return a<=b ?a :b ; } int bigF(int a, int b) { return a>=b ?a :b ; } int main() { int a, b, c, i, j, ans, t; while(scanf("%d", &t)!=EOF) { ans = INF, big = 0; scanf("%d %d", &n, &m); for(i=1; i<=MAXN; i++) /***/ for(j=1; j<=MAXN; j++) r[i][j] = r[j][i] = INF; //双向 for(i=1; i<=t; i++) { scanf("%d %d %d", &a, &b, &c); r[a][b] = minF(r[a][b], c); r[b][a] = minF(r[b][a], c); big = bigF(big, bigF(a, b)); } for(i=1; i<=n; i++) { scanf("%d", &begin[i]); dij( begin[i] ); } for(i=1; i<=m; i++) scanf("%d", &end[i]); for(i=1; i<=n; i++) for(j=1; j<=m; j++) { ans = minF(ans, ju[begin[i]][end[j]]); } printf("%d\n", ans); } return 0; }