View Code
/*poj1135Domino Effect
有n个关键的多米诺骨牌,两个多米诺骨牌中间有一排骨牌,一块骨牌倒下需要1s,从第一个关键的骨牌开始翻到,问全部骨牌翻到需要多少时间&&最后一块骨牌的位置
思路:
求每块关键骨牌翻到的时间(以为源点最小路径),每一条边全部倒下需要时间(d[u]+d[v]+val)/2;
注意:1,0->1.0s 1
*/
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 1000000000
#define MAXN 506
struct E
{
int u,v,val;
}e[MAXN*MAXN];
int w[MAXN][MAXN],vis[MAXN],d[MAXN];
int n,m;
void dijkstra(int u)
{
memset(vis,0,sizeof(vis));
for(int i = 1 ; i <= n ; i++)d[i]=(i==u ? 0 : INF);
for(int i = 1 ; i <= n ; i++)
{
int x,mi = INF;
for(int y = 1 ; y <= n ; y++)if(!vis[y]&&d[y]<=mi)mi=d[x=y];
vis[x]=1;
for(int y = 1 ; y <= n ; y++)if(!vis[y]&&w[x][y])d[y]=min(d[y],d[x]+w[x][y]);
}
}
double ans;
int ku,kv;
void DominoEffect()
{
double det,tmp;
ans=0;
for(int i=1;i<=m;i++)
{
int u=e[i].u,v=e[i].v,val=e[i].val;
det=abs(d[u]-d[v]);
//tmp=min(d[u],d[v])+det+(val-det)*0.5;
tmp=(d[u]+d[v]+val)*0.5;
if(ans<tmp)
{
ans=tmp;
if(det==val)
{
if(d[u]<d[v])kv=ku=v;
else kv=ku=u;
}
else
{
ku=min(u,v);
kv=max(u,v);
}
}
}
}
int main()
{
int u,v,val,cas=0;
while(scanf("%d%d",&n,&m)==2)
{
if(!n&&!m)break;
memset(w,0,sizeof(w));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&val);
e[i].u=u,e[i].v=v,e[i].val=val;
w[u][v]=val;
w[v][u]=val;
}
dijkstra(1);
DominoEffect();
printf("System #%d\n",++cas);
printf("The last domino falls after %.1lf seconds,",ans);
if(n==1)printf(" at key domino 1.\n\n");
else if(kv==ku)printf(" at key domino %d.\n\n",kv);
else printf(" between key dominoes %d and %d.\n\n",ku,kv);
}
}