题目大意:
多米诺骨牌游戏:给出一些关键骨牌(1~n),关键骨牌中间有一些普通骨牌,每个骨牌倒下的时间都是1 seconds,推到第一个关键骨牌,问最后一个骨牌倒下的时间和位置(可以是关键骨牌,或者是普通骨牌)。
解题思路:
本题并不难,关键是读懂题。本题可抽象成一个带权无向图,关键骨牌为带权无向图的结点,关键骨牌中间的普通骨牌数量抽象成带权边。当一个关键骨牌倒下时,之后和其有关联的普通骨牌倒下,当一个普通骨牌倒下时,之后在其后面的骨牌会倒下。使用dijkstra算法计算出当推到第一个关键骨牌后,其他关键骨牌倒下的时间lowc[i],选择一个最大时间max1(max1=max{lowc[i]|0<i<n &&}); 有可能会是普通骨牌倒下,关键骨牌之间的普通骨牌倒下的时间为:(lowc[i] + lowc[j] + 关键骨牌间的普通骨牌数目)/2,选择一个最大的时间max2,比较max1和max2的值。
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0x3f3f3f3f
#define eps 1e-6
#define M 1000
using namespace std;
struct Edge{
int x;
int y;
int l;
}edge[M*M];
int n, m;
int a, b, l;
int vis[M], lowc[M], dis[M][M];
void dijkstra(int v) {
int i, j;
for(i=0; i<n; i++) {
lowc[i] = dis[v][i];
vis[i] = 0;
}
vis[v] = 1;
int minc, u;
for(i=1; i<n; i++) {
minc = INF; u = -1;
for(j=0; j<n; j++) {
if(vis[j] == 0 && lowc[j] < minc) {
minc = lowc[j]; u = j;
}
}
vis[u] = 1;
for(j=0; j<n; j++) {
if(vis[j] == 0 && lowc[j] > lowc[u] + dis[u][j]) {
lowc[j] = lowc[u] + dis[u][j];
}
}
}
return ;
}
int main() {
int i, j, k;
int c = 1;
while(scanf("%d%d", &n, &m)) {
if(n == 0 && m == 0) break;
for(i=0; i<n; i++) {
for(j=0; j<n; j++) {
if(i == j) dis[i][j] = 0;
else dis[i][j] = INF;
}
}
for(i=0; i<m; i++) {
scanf("%d%d%d", &a, &b, &l);
dis[a-1][b-1] = l; dis[b-1][a-1] = l;
edge[i]. x = a-1; edge[i].y = b-1;
edge[i].l = l;
}
dijkstra(0);
int max1_x = 0, max1 = 0; //关键骨牌倒下的时间和序号
for(i=0; i<n; i++) {
if(lowc[i] > max1) {
max1 = lowc[i];
max1_x = i;
}
}
int max2_x, max2_y; //普通骨牌倒下的时间和两端的关键骨牌
double max2 = -1.0;
for(i=0; i<m; i++) {
double tmp = (lowc[edge[i].x] + lowc[edge[i].y] + edge[i].l) * 1.0 / 2;
if(tmp - max2 > eps) {
max2 = tmp;
max2_x = edge[i].x;
max2_y = edge[i].y;
}
}
printf("System #%d\n", c ++);
if(max1*1.0 - max2 < 0) {
printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n\n",
max2, min(max2_x + 1, max2_y + 1), max(max2_x + 1, max2_y + 1));
}
else {
printf("The last domino falls after %d.0 seconds, at key domino %d.\n\n", max1, max1_x + 1);
}
}
return 0;
}