传送门 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; }
poj 1135 最短路 dijkstra
时间: 2024-10-15 14:31:52