http://poj.org/problem?id=1135
思路:达到每个关键多米诺的时间就是与第一个关键多米诺骨牌的最短距离
与第一个关键多米诺骨牌距离最远的关键多米诺骨牌必定最晚倒下,然后
穷举每个关键多米诺骨牌和它的相邻多米诺骨牌,查找最晚倒下的多米诺骨牌
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#define M 505
#define INF 0xfffffff
#define eps 1e-8
using namespace std;
int n,m;
int g[M][M];
int dis[M];
double Max;
int s,e;
vector<int> G[M];
void dijkstra()
{
bool v[M];
int i,j,k;
int mn;
memset(v,false,sizeof(v));
for(i=1;i<=n;i++)
dis[i]=INF;
dis[1]=0;
for(i=1;i<=n;i++)
{
mn=INF;
for(j=1;j<=n;j++)
if(!v[j] && dis[j]<mn)
{
mn=dis[j];
k=j;
}
v[k]=true;
for(j=1;j<=n;j++)
if(!v[j] && dis[j]>dis[k]+g[k][j])
dis[j]=dis[k]+g[k][j];
}
}
double max(double a,double b)
{
if(a-b>eps) return a>b;
return b;
}
void solve()
{
int i,j;
Max=-1;
for(i=1;i<=n;i++)//枚举每个点
{
for(j=0;j<G[i].size();j++)//枚举与i相邻的点
{
int u=G[i][j];
double time;
double tmp=(g[i][u]-abs(dis[i]-dis[u]))*1.0/2;
if(fabs(tmp)<=eps)
{
time=max(dis[i]*1.0,dis[u]*1.0);
if(time>Max)
{
Max=time;
s=-1;
e=dis[i]>dis[u]?i:u;
}
}
else
{
time=max(dis[i]*1.0,dis[u]*1.0)+tmp;
if(time>Max)
{
Max=time;
s=i<u?i:u;
e=i>u?i:u;
}
}
}
}
}
int main()
{
int i,j;
int cas=1;
while(scanf("%d%d",&n,&m)&&n+m)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
g[i][j]=INF;
memset(G,0,sizeof(G));
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=c;
G[a].push_back(b);
G[b].push_back(a);
}
if(n!=1)
{
dijkstra();
solve();
}
printf("System #%d\n",cas++);
if(n==1)
printf("The last domino falls after 0.0 seconds, at key domino 1.\n\n");
else if(s==-1)
printf("The last domino falls after %.1f seconds, at key domino %d.\n\n",Max,e);
else
printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n\n",Max,s,e);
}
return 0;
}
/*
4 5
1 2 1
1 3 2
2 3 100
2 4 3
3 4 4
*/