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 }

 

posted @ 2021-05-03 20:18  acmloser  阅读(38)  评论(0编辑  收藏  举报