The last domino falls after 27.0 seconds, at key domino 2.
样例输出:
The last domino falls after 7.5 seconds, between key dominoes 2 and 3.
算是模版Dijkstra题目了,多了判断哪种最优解的情况。
a) 先计算每一张关键牌倒下的dist[i]。这需要利用Dijkstra 算法求第1 张关键牌到其他每
张关键牌的最短路径。然后取dist[i]的最大值,设为max1。
b) 计算每一行完全倒下的时间。设每一行的两端的关键牌为i 和j,则这一行完全倒下的时
间为(dist[i] + dist[j] + edge[i][j])/2.0,其中edge[i][j]为连接第i、j 两张关键牌的行倒下
所花的时间。取所有行完全倒下时间的最大值,设为max2。
c) 如果max2 > max1,则是第②种情形;否则是第①种情形。
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #define MAX 600 #define INF 0x7FFFFFFF # define eps 1e-5 using namespace std; int n,m; int edge[MAX][MAX],visit[MAX],dist[MAX];//边的信息,访问,最短距离 void dijkstra(int u0) { int i,j,v; for(i=1; i<=n; i++)//初始化 { dist[i] = edge[u0][i]; } visit[u0] = 1; for(j=0; j<n-1; j++) { int min = INF; for(i=1; i<=n; i++) { if(!visit[i] && min > dist[i]) { min = dist[i]; v = i; } } visit[v] = 1;//点v与源点同一集合 for(i=1; i<=n; i++)//随着新的顶点加入,更新dist值 { if(!visit[i] && edge[v][i] < INF && edge[v][i] + dist[v] < dist[i]) dist[i] = edge[v][i] + dist[v]; } } } int main() { int i,j,a,b,c,tt = 1; while(scanf("%d%d",&n,&m)) { if(n==0 && m==0) break; for(i=1; i<=n; i++)//初始化 for(j=1; j<=n; j++) { if(i == j) edge[i][j] = 0; else edge[i][j] = INF; } for(i=0; i<m; i++)//构图 { scanf("%d%d%d",&a,&b,&c); edge[a][b] = c; edge[b][a] = c; } memset(visit,0,sizeof(visit)); dijkstra(1);//求出1到所有定点最短路 double max1 = -10000000; int index; for(i=1; i<=n; i++)//情况a { if(max1 < dist[i]) { max1 = dist[i]*1.0; index = i; } } double max2 = -10000000; int index1,index2; for(i=1; i<=n; i++)//情况b for(j=1; j<=n; j++) { if(edge[i][j] != INF && i < j)//i < j 算是优化,有了它就是0ms,没有就是16ms { if(max2 < (dist[i]+dist[j]+edge[i][j])/2.0) { max2 = (dist[i]+dist[j]+edge[i][j])/2.0; index1 = i; index2 = j; } } } printf("System #%d\n",tt++); if(max1 >= max2)//选出符合的情况 printf("The last domino falls after %.1f seconds, at key domino %d.\n",max1,index); else printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n",max2,index1,index2); printf("\n"); } return 0; }