题意
分析
这题几乎就是一条dijkstra的问题。但是,如何考虑倒在中间?
要意识到这题求什么:单源最短路的最大值。那么有没有更大的?倒在中间有可能会使它更大。
但是要注意一个问题:不要把不存在的边(边长为inf)算进去;另外,n=1的情况需要注意。
代码
// Origin:
// Theme: Graph Theory (Basic)
// Date: 080618
// Author: Sam X
//#include <bits/stdc++.h>
#include <iostream>
#include <utility>
#include <iomanip>
#include <cstring>
#include <cmath>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef pair<int,int> pi;
typedef pair<int,pi> pii;
int dist[505][505];
int main()
{
int n,m,kase=0;
while(cin>>n>>m)
{
if(!n && !m) break;
memset(dist,0x3f,sizeof(dist));
rep(i,1,n) dist[i][i]=0;
rep(i,1,m)
{
int x,y,z; cin>>x>>y>>z;
dist[x][y]=dist[y][x]=z;
}
if(n==1)
{
cout<<"System #"<<++kase<<"
The last domino falls after 0.0 seconds, at key domino 1.
";
continue;
}
int d[505]; memset(d,0x3f,sizeof(d));
d[1]=0;
bool vis[505]; ZERO(vis);
rep(i,1,n)
{
int mind=0x3f3f3f3f,x=-1;
rep(j,1,n) if(!vis[j] && d[j]<mind) mind=d[x=j];
if(x==-1) break;
vis[x]=true;
rep(i,1,n)
{
d[i]=min(d[i],d[x]+dist[x][i]);
}
}
//rep(i,1,n) cout<<d[i]<<" "; cout<<endl;
double ans=-1,ans_mid=-1;
int end=-1,lend=-1,rend=-1,maxd=-1;
bool ismid=false;
rep(i,2,n)
{
if(d[i]>ans)
{
ans=d[end=i];
}
//maxd=max(d[i],maxd);
}
rep(i,1,n)
{
rep(j,i+1,n)
{
if(dist[i][j]==0x3f3f3f3f) continue;
double tmp=(d[i]+d[j]+dist[i][j])/2.0;
if(tmp>ans_mid)
{
lend=i; rend=j;
ans_mid=max(tmp,ans_mid);
}
}
}
ismid=ans_mid-ans>1e-8;
cout<<"System #"<<++kase<<endl<<"The last domino falls after "<<fixed<<setprecision(1)<<double(ismid?ans_mid:ans)<<" seconds, ";
if(!ismid)
{
cout<<"at key domino "<<end<<"."<<endl;
}
else
{
cout<<"between key dominoes "<<lend<<" and "<<rend<<"."<<endl;
}
cout<<endl;
}
return 0;
}