首先dijkstra求出最短路,求的时候顺便求出1能到的最长路记为ans * 2.
枚举每条边,满足dis[i] + dis[j] + g[i][j] > ans 更新ans.
最后输出答案ans / 2;
/*
* ZOJ 1298.cpp
*
* Created on: May 27, 2013
* Author: root
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <memory.h>
#include <limits.h>
using namespace std;
const int maxn = 505;
struct edge{
int v, next;
double w;
}es[maxn * 5];
struct node{
int i;
double v;
node(int ii = 0, double vv = 0):i(ii), v(vv){}
bool operator<(const node & rhs)const{
return v > rhs.v;
}
};
int head[maxn], n, m, fro, tar, type;
double ans;
double dis[maxn];
bool vis[maxn];
void addEdge(int u, int v, double w, int eidx){
es[eidx].v = v;
es[eidx].w = w;
es[eidx].next = head[u];
head[u] = eidx;
}
void dijkstra(){
type = 0;
for(int i = 1; i <= n; ++i){
dis[i] = INT_MAX;
}
memset(vis, 0, sizeof(vis));
dis[1] = 0;
priority_queue<node> q;
q.push(node(1, 0));
while(q.size()){
node t = q.top();
q.pop();
int u = t.i;
if(vis[u])continue;
vis[u] = 1;
if(t.v >= ans){
fro = u;
ans = t.v;
}
for(int ne = head[u]; ne != -1; ne = es[ne].next){
int v = es[ne].v;
double w = es[ne].w;
if(dis[v] > dis[u] + w && !vis[v]){
dis[v] = dis[u] + w;
q.push(node(v, dis[v]));
}
}
}
}
int main(){
int cas = 1;
while(scanf("%d %d", &n, &m)){
if(!n && !m)break;
memset(head, -1, sizeof(head));
int eidx = 0;
for(int i = 0; i < m; ++i){
int u, v;
double w;
scanf("%d %d %lf", &u, &v, &w);
addEdge(u, v, w, eidx++);
addEdge(v, u, w, eidx++);
}
ans = 0;
fro = 1;
dijkstra();
ans *= 2;
for(int i = 1; i <= n; ++i){
for(int ne = head[i]; ne != -1; ne = es[ne].next){
int u = i, v = es[ne].v;
double w = es[ne].w;
if(dis[u] + dis[v] + w > ans){
fro = u, tar = v;
type = 1;
ans = dis[u] + dis[v] + w;
}
}
}
printf("System #%d\n", cas++);
if(type == 0){
if(m == 0) fro = 1;
printf("The last domino falls after %.1lf seconds, at key domino %d.\n", ans / 2, fro);
}else{
printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n", ans / 2, fro, tar);
}
printf("\n");
}
return 0;
}