POJ 1135 Domino Effect(最短路径)

题意
有m排放置好的多米诺骨牌,每排的头尾骨牌称为“关键骨牌”,共有n个关键骨牌,每排多米诺倒下需要L秒,关键骨牌倒下的时间忽略不计。推倒关键骨牌1,求最后一个骨牌倒下的时间及位置。(若最后一个倒下的骨牌不是关键骨牌,则按升序输出这个骨牌所在的那一排的两端的关键骨牌)

样例输入
2 1
1 2 27
3 3
1 2 5
1 3 5
2 3 5
0 0

样例输出
System #1
The last domino falls after 27.0 seconds, at key domino 2.

System #2
The last domino falls after 7.5 seconds, between key dominoes 2 and 3.

思路
无向图,先用dijkstra算法求出从关键骨牌1到各个关键骨牌的最短路径(即最短耗时)。而与最短路径不相干的边倒下的时刻,则是关键骨牌1到这条边两端的关键骨牌所需的最短时间之和,再加上这条边倒下所需的时间,再除以2。(理解这一点是这道题的关键,类似与相遇问题)最后,只要比较关键骨牌1到某个关键骨牌的最短路径耗时 和 某条边的倒下的时刻,取两者中较大的一方,即可得出结论。

注意点
由于关键骨牌倒下时间忽略不计,所以当输入数据只有1个骨牌时,耗时为0.0,倒下的关键骨牌为1本身。

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <string.h>
 4 #include <queue>
 5 using namespace std;
 6 
 7 const int N = 510, INF = 0x3f3f3f3f;
 8 int graph[N][N];
 9 
10 void SPFA(int n)
11 {
12     queue<int> q;
13     bool vis[N] = {0};
14     vis[0] = true;
15     int D[N];
16     for(int i=0; i<n; ++i)
17     {
18         D[i] = graph[0][i];
19         if(graph[0][i] != INF)
20         {
21             q.push(i);
22             vis[i] = true;
23         }
24     }
25     while(!q.empty())
26     {
27         int x = q.front();
28         for(int i=0; i<n; ++i)
29         {
30             int dis = D[x] + graph[x][i];
31             if(dis < D[i])
32             {
33                 D[i] = dis;
34                 if(!vis[i])
35                 {
36                     q.push(i);
37                     vis[i] = true;
38                 }
39             }
40         }
41         q.pop();
42         vis[x] = false;
43     }
44     D[0] = 0;
45     int Max1 = 0, Max2 = 0, sum, tag1, tag21, tag22;
46     for(int i=1; i<n; ++i)
47         if(D[i] > Max1)
48             Max1 = D[i], tag1 = i;
49     for(int i=0; i<n; ++i)
50     {
51         for(int j=i+1; j<n; ++j)
52         {
53             if(graph[i][j] != INF)
54                 sum = D[i] + D[j] + graph[i][j];
55             if(sum > Max2)
56                 Max2 = sum, tag21 = i, tag22 = j;
57         }
58     }
59     double ans = (double)Max2 / 2;
60     if(ans <= (double)Max1)
61         printf("The last domino falls after %.1lf seconds, at key domino %d.

", (double)Max1, tag1+1);
62     else
63         printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.

", ans, tag21+1, tag22+1);
64     return ;
65 }
66 
67 int main(void)
68 {
69     int n, m, u, v, w;
70     for(int t=0; scanf("%d %d", &n, &m), n+m; )
71     {
72         memset(graph, INF, sizeof(graph));
73         for(int i=0; i<m; ++i)
74         {
75             scanf("%d %d %d", &u, &v, &w);
76             --u, --v;
77             graph[u][v] = w;
78             graph[v][u] = w;
79         }
80         printf("System #%d
", ++t);
81         if(n == 1)
82             printf("The last domino falls after 0.0 seconds, at key domino 1.

");
83         else
84             SPFA(n);
85     }
86     return 0;
87 }

测试数据

2 1
1 2 27
3 3
1 2 5
1 3 5
2 3 5
1 0
5 7   
1 2 1
1 3 2
1 4 3
1 5 5
2 3 1
3 4 1
4 5 1
4 5
1 2 3
1 3 3
1 4 5
3 4 2
2 3 9
3 3
1 3 1
1 2 3
2 3 3
0 0
in
System #1
The last domino falls after 27.0 seconds, at key domino 2.

System #2
The last domino falls after 7.5 seconds, between key dominoes 2 and 3.

System #3
The last domino falls after 0.0 seconds, at key domino 1.

System #4
The last domino falls after 4.5 seconds, between key dominoes 1 and 5.

System #5
The last domino falls after 7.5 seconds, between key dominoes 2 and 3.

System #6
The last domino falls after 3.5 seconds, between key dominoes 2 and 3.
out
原文地址:https://www.cnblogs.com/corvey/p/5247265.html