计算多米诺骨牌推倒推倒的时间。
这里先用Dijkstra计算单源最短路径,然后在其他不在该路径中的边所需要推倒的时间,time[i] + time[j] + edge[i][j]/2即可。这里要枚举
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define NLEN 510
#define INF 1000000
int edge[NLEN][NLEN];
int _time[NLEN];
int s[NLEN];
void dijkstra(int n, int m) {
memset(s, 0, sizeof(s));
memset(_time, 0, sizeof(_time));
for(int i = 0; i < n; i++) {
_time[i] = edge[0][i];
}
s[0] = 1;
_time[0] = 0;
for(int i = 1; i < n; i++) {
int min = INF;
int imin = 0;
for(int j = 0; j < n; j++) {
if(!s[j] && _time[j] < min) {
imin = j;
min = _time[j];
}
}
s[imin] = 1;
for(int j = 0; j < n; j++) {
if(!s[j] && edge[imin][j] < INF && _time[j] > _time[imin] + edge[j][imin]) {
_time[j] = _time[imin] + edge[j][imin];
}
}
}
double max_time1 = -INF;
int pos;
for(int i = 0; i < n; i++) {
if(_time[i] > max_time1) {
max_time1 = _time[i];
pos = i;
}
}
double max_time2 = -INF;
int pos1, pos2;
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if((_time[i]+_time[j]+edge[i][j])/2.0 > max_time2 && edge[i][j] < INF) {
max_time2 = (_time[i] + _time[j] + edge[i][j])/2.0;
pos1 = i;
pos2 = j;
}
}
}
if(max_time1 >= max_time2) {
printf("The last domino falls after %.1lf seconds, at key domino %d.\n\n", max_time1, pos+1);
}
else {
printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n", max_time2, pos1+1, pos2+1);
}
}
int main() {
int n, m;
int cse = 1;
while(scanf("%d%d", &n, &m), n!=0) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
edge[i][j] = INF;
}
}
for(int i = 0; i < m; i++) {
int x, y, t;
scanf("%d%d%d", &x, &y, &t);
x--;
y--;
edge[x][y] = edge[y][x] = t;
}
printf("System #%d\n", cse++);
dijkstra(n, m);
}
return 0;
}