Shortest Path HDU - 3631
考察:Floyd
思路:
每次0操作都是加入一个点,这个操作有点像Floyd,Floyd算法也是每次操作加入一个点,然后更新.但直接每次加入新点就Floyd会超时,所以要对Floyd算法优化.
每次加入一个新点,就直接更新与该点有关的边.但有个误区是不能只更新已加入点与新点直接的边.比如1->0->4这条边,如果先加入0再加入4这样1->0->4就无法更新.所以只能更新新点与其他所有点的距离.
那么这样最短路是否正确.如果起点和终点不在集合里,那么不用求最短路.如果在,中间点与起点,终点距离不等于INF,那一定更新过该点与其他所有点的边.所以这样求的最短路一定是包含所有集合的点.
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int N = 310,INF = 0x3f3f3f3f; 5 int g[N][N],op,x,y,kcase,n,m,T; 6 bool st[N]; 7 int main() 8 { 9 while(scanf("%d%d%d",&n,&m,&T)!=EOF&&(n+m+T)) 10 { 11 if(kcase) printf("\n"); 12 printf("Case %d:\n",++kcase); 13 memset(g,0x3f,sizeof g); memset(st,0,sizeof st); 14 while(m--) 15 { 16 int a,b,w; scanf("%d%d%d",&a,&b,&w); 17 g[a][b] = min(g[a][b],w); 18 } 19 for(int i=0;i<n;i++) g[i][i] = 0; 20 while(T--) 21 { 22 scanf("%d%d",&op,&x); 23 if(!op) 24 { 25 if(st[x]) printf("ERROR! At point %d\n",x); 26 else{ 27 st[x] = 1; 28 for(int i=0;i<n;i++) 29 for(int j=0;j<n;j++) 30 { 31 if(g[i][x]<INF&&g[x][j]<INF) 32 g[i][j] = min(g[i][x]+g[x][j],g[i][j]); 33 } 34 } 35 }else{ 36 scanf("%d",&y); 37 if(!st[x]||!st[y]) 38 { 39 printf("ERROR! At path %d to %d\n",x,y); 40 continue; 41 } 42 if(g[x][y]==INF) puts("No such path"); 43 else printf("%d\n",g[x][y]); 44 } 45 } 46 } 47 return 0; 48 }