ZOJ1298 POJ1135
题意就不说了。。
1.如果最后倒下的牌是关键牌,其时间及位置是第一张关键牌到其他关键牌中最短路径的最大值及对应的关键牌
2.最后倒下的牌是两张关键牌之间的某张普通牌,时间t = (dis[i] + dis[j] + g[i][j])/2.0;位置在这两张关键牌之间
3.比较上面两种情况的最大值,然后决定取那种方法
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 8 #define inf 9999999 9 #define N 505 10 double dis[N]; 11 int vis[N],g[N][N]; 12 int n,m,cas=1; 13 14 void solve(int st) 15 { 16 for(int i=0; i<n; i++) 17 { 18 dis[i] = g[st][i]; 19 vis[i] = 0; 20 } 21 dis[st] = 0;vis[st] = 1; 22 for(int i=1; i<n; i++) 23 { 24 double mindis = inf ; 25 int idx = -1; 26 for(int j=0; j<n; j++) 27 { 28 if(!vis[j] && dis[j] < mindis) 29 { 30 mindis = dis[j]; 31 idx = j; 32 } 33 } 34 if(idx == -1) return ; 35 vis[idx] = 1; 36 for(int j=0; j<n; j++) 37 { 38 if(!vis[j] && dis[j] > dis[idx] + g[idx][j]) 39 dis[j] = dis[idx] + g[idx][j]; 40 } 41 } 42 43 double max1 = 0; 44 int pos=0; //这里要注意,不初始化为0在POJ可以过,在ZOJ就跪了。。 45 for(int i=0; i<n; i++) 46 { 47 if(dis[i] > max1) 48 { 49 max1 = dis[i]; 50 pos = i; 51 } 52 } 53 double max2 = 0,t; 54 int pos1,pos2; 55 for(int i=0; i<n; i++) 56 for(int j=0; j<n; j++) 57 { 58 if(g[i][j] !=inf) 59 { 60 t = (dis[i] + dis[j] + g[i][j])/2.0; 61 if(t > max2) 62 { 63 max2 = t; 64 pos1 = i; 65 pos2 = j; 66 } 67 } 68 } 69 printf("System #%d\n",cas++); 70 if(max2>max1) 71 printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n\n",max2,pos1+1,pos2+1); 72 else 73 printf("The last domino falls after %.1f seconds, at key domino %d.\n\n",max1,pos+1); 74 } 75 76 int main() 77 { 78 while(scanf("%d%d",&n,&m)!=EOF) 79 { 80 if(n==0 && m==0) break; 81 for(int i=0; i<n; i++) 82 for(int j=0; j<n; j++) 83 { 84 if(i==j) g[i][j] = 0; 85 else g[i][j] = inf; 86 } 87 int u,v,w; 88 while(m--) 89 { 90 scanf("%d%d%d",&u,&v,&w); 91 u--;v--; 92 if(w < g[u][v]) 93 g[u][v] = g[v][u] = w; 94 } 95 solve(0); 96 } 97 return 0; 98 }