题目链接:http://poj.org/problem?id=1135
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8736 | Accepted: 2186 |
Description
While this is somewhat pointless with only a few dominoes, some people went to the opposite extreme in the early Eighties. Using millions of dominoes of different colors and materials to fill whole halls with elaborate patterns of falling dominoes, they created (short-lived) pieces of art. In these constructions, usually not only one but several rows of dominoes were falling at the same time. As you can imagine, timing is an essential factor here.
It is now your task to write a program that, given such a system of rows formed by dominoes, computes when and where the last domino falls. The system consists of several ``key dominoes'' connected by rows of simple dominoes. When a key domino falls, all rows connected to the domino will also start falling (except for the ones that have already fallen). When the falling rows reach other key dominoes that have not fallen yet, these other key dominoes will fall as well and set off the rows connected to them. Domino rows may start collapsing at either end. It is even possible that a row is collapsing on both ends, in which case the last domino falling in that row is somewhere between its key dominoes. You can assume that rows fall at a uniform rate.
Input
The following m lines each contain three integers a, b, and l, stating that there is a row between key dominoes a and b that takes l seconds to fall down from end to end.
Each system is started by tipping over key domino number 1.
The file ends with an empty system (with n = m = 0), which should not be processed.
Output
Sample Input
2 1 1 2 27 3 3 1 2 5 1 3 5 2 3 5 0 0
Sample Output
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.
刚开始看不懂题,后来好容易看懂了还没思路,完了,补课,看模板,找资料,终于理清了思路,还WA了十好几次,后来一怒之下 把代码整个重新写了一遍,AC了
基本思路::参考来自:http://www.cnblogs.com/jackge/archive/2013/04/12/3016578.html算是模版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 <stdio.h> # include <string.h> const int INF = 0x3fffffff; ///用于初始化的最大值 int map[510][510],d[510],mark[510]; int main() { int n,m,min,v,k,K=1,POS,POSA,POSB,i,j,a,b,c; double time_1,time_2,s; ///两个 double型的变量 用于保存两种情况对应的时间 while(scanf("%d%d",&n,&m),n+m) { for(i = 0; i <= n; i++) //初始化 map { for(j = 0; j <= n; j++) map[i][j] = INF; map[i][i] = 0; ///千万别忘了这个 } memset(mark,0,sizeof(mark)); //初始化 mark for(i = 0; i < m; i++) { scanf("%d %d %d",&a,&b,&c); map[b][a] = map[a][b] = c; } /** ∨迪杰斯特拉 求点1到各点的最短路 ∨ **/ mark[1] = 1; for(i = 1; i <= n; i++) d[i] = map[1][i]; d[1] = 0; for(i = 1 ;i <= n ;i++) { min = INF; for(j = 1; j <= n; j++) if(!mark[j] && min > d[j]) { v = j; min = d[j]; } mark[v] = 1; for(k = 1 ;k <= n ;k++) if(!mark[k] && min + map[v][k] < d[k]) d[k] = min + map[v][k]; } /** ∧ 迪杰斯特拉结束 ∧ **/ time_1 = -INF; /// 第一种情况∨ for(i = 1 ;i <= n ;i++) { if(time_1 < d[i])time_1 = d[i] * 1.0;///最大时间 POS = i; ///记录位置 } time_2 = -INF;///第二种情况∨ for(i = 1 ;i <= n; i++) { for(j = i + 1; j <= n; j++) if(map[i][j] != INF) { s =( d[i] + d[j] + map[i][j] )* 0.5; if(time_2 < s) ///记录最大时间与位置 { time_2 = s; POSA = i; POSB = j; } /// i < j 所以 POSA < POSB } } if(time_2 <= time_1)printf("System #%d\nThe last domino falls after %.1lf seconds, at key domino %d.\n\n",K++,time_1,POS); else printf("System #%d\nThe last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n",K++,time_2,POSA,POSB); /**输出,每组结果后输出一空行**/ } return 0; }
运行结果:
PS:这题写着真费劲 不知道为什么 ,这份代码 用GCC 提交 显示Wrong Answer