poj 3613【Cow Relays】

首先看题解,看到的是floyd,然后就往floyd方向去想,想不咋通,之后就问了队长,队长解释了一下就清楚了

这一题用的是floyd和二分的思想,如果只是floyd的思想就是求任意两点之间距离为k(1<=k<=N)条边的最短距离,然后在此基础上求k+1条边的最短距离……

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int maxlen = 1000+10;
 5 int N,T,S,E;
 6 int map[maxlen][maxlen];
 7 int sign[maxlen];
 8 int tmp[maxlen][maxlen];
 9 bool used[maxlen];
10 int ans[maxlen][maxlen];
11 int cnt;
12 
13 void floyd(int a[][maxlen],int b[][maxlen])
14 {
15     //memset(tmp,-1,sizeof(tmp));
16     for(int k = 0;k < cnt;k ++)
17     {
18         for(int i = 0;i < cnt;i ++)
19         {
20             if(a[sign[i]][sign[k]] != -1)
21             {
22                 for(int j = 0;j < cnt;j ++)
23                 {
24                     if(b[sign[k]][sign[j]] != -1)
25                     {
26                         if(tmp[sign[i]][sign[j]] == -1 || tmp[sign[i]][sign[j]] > b[sign[k]][sign[j]] + a[sign[i]][sign[k]])
27                         {
28                             tmp[sign[i]][sign[j]] = a[sign[i]][sign[k]] + b[sign[k]][sign[j]];
29                         }
30                     }
31                 }
32             }
33         }
34     }
35 
36    for(int i = 0;i < cnt;i ++)
37    {
38        for(int j = 0;j < cnt;j ++)
39        {
40            a[sign[i]][sign[j]] = tmp[sign[i]][sign[j]];
41            tmp[sign[i]][sign[j]] = -1;
42        }
43    }
44    //memcpy(a,tmp,sizeof(tmp));这里用这个就会超时,/可怜
45 }
46 
47 void solve(int k)
48 {
49     memset(ans,-1,sizeof(ans));
50     memset(tmp,-1,sizeof(tmp));
51     for(int i = 0;i < maxlen;i ++)
52     {
53         ans[i][i] = 0;
54     }
55     while(k)
56     {
57         if(k%2)
58         {
59             floyd( ans,map);
60         }
61         floyd(map,map);
62         k = k >> 1;
63     }
64 }
65 
66 int main()
67 {
68     while(scanf("%d%d%d%d",&N,&T,&S,&E) == 4)
69     {
70         memset(map,-1,sizeof(map));
71         memset(used,false,sizeof(used));
72         cnt = 0;
73         for(int i = 0;i < T;i ++)
74         {
75             int p,s,t;
76             scanf("%d%d%d",&p,&s,&t);
77             if(map[s][t] == -1 || map[s][t] > p)
78             {
79                 map[s][t] = p;
80                 map[t][s] = p;
81             }
82             if(!used[s])
83             {
84                 used[s] = true;
85                 sign[cnt ++] = s;
86             }
87             if(!used[t])
88             {
89                 used[t] = true;
90                 sign[cnt ++] = t;
91             }
92         }
93         solve(N);
94         printf("%d\n",ans[S][E]);
95     }
96     return 0;
97 }
原文地址:https://www.cnblogs.com/Shirlies/p/2658440.html