hdu 2680 Choose the best route【dijstra+反向建图】
http://acm.hdu.edu.cn/showproblem.php?pid=2680
题意:给出顶点数和路径总数及要到达的终点,再给出可以到达终点的多个起点,输出这些起点中到终点的最短路径。
思路:如果找每个起点到终点的距离,最后比较出最小值,会tle(亲测有效),正解思路是反向建图,把题目所给的终点当作起点,多个起点当作终点,用一次dijstra求起点到每个顶点的最短路径,最后遍历查找起点到每个终点的路径的最短路。
看了别人的题解才知道,还有一个地方比较坑,同一路径,取权值最小的边,不过平时自己就习惯了判断自重边,反正也不影响结果,想不到这次避开了这个坑点。
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f #define N 1100 int w[N][N],dis[N],book[N],num[N]; int main() { int n,m,s,t1,t2,t3,ans,min1,u,x,i,j; while(scanf("%d%d%d",&n,&m,&s)!=EOF) { for(i = 0; i <= n; i ++) for(j = 0; j <= n; j ++) w[i][j] = inf; for(i = 1; i <= m; i ++) { scanf("%d%d%d",&t1,&t2,&t3); if(t3 < w[t2][t1])//判断自重边 w[t2][t1] = t3;//反向建图 } scanf("%d",&x); for(i = 1; i <= x; i ++) scanf("%d",&num[i]); memset(book,0,sizeof(book)); for(i = 1; i <= n; i ++) dis[i] = w[s][i]; book[s] = 1; for(i = 1; i < n; i ++) { min1 = inf; for(j = 1; j <= n; j ++) if(!book[j]&&dis[j]<min1) { min1 = dis[j]; u = j; } book[u] = 1; for(j = 1; j <= n; j ++) if(!book[j]&&dis[j] > dis[u]+w[u][j]) dis[j] = dis[u]+w[u][j]; } ans = inf; for(i = 1; i <= x; i ++) ans = min(ans,dis[num[i]]);//取反转图后起点到多个终点的最小权值 if(ans == inf) printf("-1\n"); else printf("%d\n",ans); } return 0; }