http://poj.org/problem?id=1135
经过无数的WA和PE终于AC。。
最短路的模板。
1)dis[i]表示i到源点1的最短路径,代表每一张关键牌倒下的时间,并求出最大的最短路径ans1。
2)枚举任意两边,计算每一行倒下的时间,设每一行两端的关键牌是i,j。那么这一行完全倒下时间是(dis[i]+dis[j]+map[i][j])/2.0,并求出最大值ans2.
3)比较ans1与ans2,取较大者。
#include <stdio.h> #include <string.h> #include <algorithm> #define LL long long #define _LL __int64 using namespace std; const int maxn = 510; const int INF = 0x3f3f3f3f; int n,m; int map[maxn][maxn]; int dis[maxn],vis[maxn],maxdis,maxpos; void dijstra() { memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); maxdis = -INF; vis[1] = 1; for(int i = 1; i <= n; i++) dis[i] = map[1][i]; for(int i = 1; i < n; i++) { int min = INF,pos = 1; for(int j = 1; j <= n; j++) { if(!vis[j] && dis[j] < min) { min = dis[j]; pos = j; } } if(min == INF) break; vis[pos] = 1; if(maxdis < min) { maxdis = min; maxpos = pos; } for(int j = 1; j <= n; j++) { if(!vis[j] && dis[j] > dis[pos] + map[pos][j]) dis[j] = dis[pos] + map[pos][j]; } } } void solve() { int pl = -1,pr = -1; double ans2 = (double)maxdis; double ans1 = -INF; for(int i = 1; i <= n; i++) { for(int j = i+1; j <= n; j++) { if(map[i][j] != INF) { double res = ( dis[i]+dis[j] + map[i][j])/2.0; if(res > ans1) { ans1 = res; pl = i; pr = j; } } } } if(ans1 > ans2) printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n",ans1,pl,pr); else printf("The last domino falls after %.1f seconds, at key domino %d.\n",ans2,maxpos); } int main() { int item = 1; while(~scanf("%d %d",&n,&m) && (n || m)) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i == j) map[i][j] = 0; else map[i][j] = INF; } } int u,v,w; for(int i = 1; i <= m; i++) { scanf("%d %d %d",&u,&v,&w); map[u][v] = map[v][u] = w; } printf("System #%d\n",item++); if(n == 1) { printf("The last domino falls after 0.0 seconds, at key domino 1.\n\n"); continue; } dijstra(); solve(); printf("\n"); } return 0; }
poj 3069Saruman's Army 贪心,布布扣,bubuko.com
原文:http://blog.csdn.net/iweberxie/article/details/23884999