传送门 http://poj.org/problem?id=1135
建模分两部分:1、如果最后是关键牌倒下,那么找最短路中最长的就行--最远的倒下,其他的牌一定倒下,所以找最远的最短路
2、如果最后是普通牌倒下,那么找三角形,三角形周长的一半就是倒下的位置
到底是情况1还是情况2,自己在脑子模拟一下就能想到,还是那句话,最难倒下的倒下了,其他的一定都倒下了,若第二种情况的时间比第一种长,那么就是第二种,反之,第一种
上代码
/**********************************\
poj 1135 by pilgrim
无向图边没来回弄
少个空行PE....
2014.6.23
\**********************************/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
const int SIZE = 500+10;
const int INF = 2000000000;
double e[SIZE][SIZE], d[SIZE];
bool s[SIZE];
int n,m;
void Init()
{
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
e[i][j]=INF,d[i]=INF;
}
void AddEdge()
{
int u,v;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);/*最小的下标为0*/
scanf("%lf",&e[u-1][v-1]);
e[v-1][u-1]=e[u-1][v-1];
}
}
void dij(int cnt)
{
for(int i=0;i<n;i++)
{
d[i]=e[0][i];
s[i]=0;
}
d[0]=0,s[0]=1;
for(int i=0;i<n-1;i++)
{
int mmin = INF,u=0;
for(int j=0;j<n;j++)
if(!s[j] && d[j] <mmin)
{
u=j;mmin=d[j];
}
s[u]=1;
for(int k=0;k<n;k++)
{
if(!s[k] && e[u][k] < INF && d[u]+e[u][k]<d[k])
d[k]=d[u]+e[u][k];
}
}
double maxt1=-INF,maxt2=-INF,tmp;
int pos,poss,pose;
for(int i=0;i<n;i++)
if(maxt1<d[i])
{
maxt1=d[i];
pos=i;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(d[i] <INF && d[j] < INF && e[i][j] < INF)
{
tmp=(d[i]+d[j]+e[i][j])/2.0;//
if(tmp>maxt2)
{
maxt2=tmp;
poss=i,pose=j;
}
}
}
printf("System #%d\n",cnt);
if(maxt2>maxt1)printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n",maxt2,poss+1,pose+1);
else printf("The last domino falls after %.1lf seconds, at key domino %d.\n",maxt1,pos+1);
putchar('\n');
}
int main()
{
int ncase=1;
while(~scanf("%d%d",&n,&m), n+m)
{
Init();
AddEdge();
dij(ncase++);
}
return 0;
}