标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10454 | Accepted: 2590 |
Description
Input
Output
Sample Input
2 1 1 2 27 3 3 1 2 5 1 3 5 2 3 5 0 0
Sample Output
System #1 The last domino falls after 27.0 seconds, at key domino 2. System #2 The last domino falls after 7.5 seconds, between key dominoes 2 and 3.
Source
题解:
这是一道最短路径题目,但是要判断哪种最优解的情况。设res为最后一张牌倒下的时刻,p1和p2记录的是最后倒下的关键牌的序号1。
a) 如果最后一张倒下的是关键牌。利用Dijkstra 算法求第1 张关键牌到其他每张关键牌的最短路径,保存在dis[i]。然后取dis[i]的最大值,设为res,p0..记录关键牌序号。
b) 如果最后一张倒下的是两张关键牌之间的普通牌。设该行两端的关键牌为i 和j,他们以每秒一个单位的速度相向而行,设i和j分别经过t1和t2秒相遇,i和j之间的距离为map[i][j],求i和j在什么时刻相遇。不难列出方程:t1+t2=map[i][j],dis[i]+map[i][j]=dis[j]+map[i][j]。则i和j相遇的时刻为t=(dis[i] + dis[j] +map[i][j])/2.0。res=min(res,t)。p1和p2记录两张关键牌的序号。(注意:要满足dis[i]+map[i][j]>dis[j]并且dis[j]+map[i][j]>dis[i]才应该计算t值)
c) 如果gard==1,则是a情况;否则是b情况(如果b情况成立,pos_j的值应该改变了)。
每一次AC背后都是无数次WA
对比两次的读入(只有读入不同)
WA代码
#include<cstdio> #include<iostream> #include<cstring> #include<climits> #include<cstdlib> using namespace std; #define N 501 #define inf INT_MAX int n,m,tot,map[N][N],vis[N],dis[N]; int main(){ while(scanf("%d%d",&n,&m)==2&&n&&m){ memset(map,0,sizeof map); memset(vis,0,sizeof vis); memset(dis,0,sizeof dis); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); map[u][v]=map[v][u]=w; } vis[1]=1; for(int i=1;i<=n;i++){ dis[i]=(map[1][i]!=0?map[1][i]:inf); } int t=1; dis[1]=0;//dijkstra for(int i=1;i<n;i++){ int mi=inf;t=1; for(int j=1;j<=n;j++){ if(!vis[j]&&dis[j]<mi){ t=j; mi=dis[j]; } } vis[t]=1; for(int j=1;j<=n;j++){ if(!vis[j]&&map[t][j]!=0&&dis[j]>dis[t]+map[t][j]){ dis[j]=dis[t]+map[t][j]; } } } int p0=1,p1=1,p2=1,gard=1;//开始找关键牌 double res=-inf; for(int i=1;i<=n;i++){ if(res<dis[i]){ res=dis[i]; p0=i; } } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ double x1=1.0*(dis[i]+dis[j]+map[i][j])/2.0; if(map[i][j]&&x1>res){ gard=0; res=x1; p1=i; p2=j; } } } printf("System #%d\n", ++tot); if(gard==1){ printf("The last domino falls after %.1lf seconds, at key domino %d.\n", res, p0); } else{ if(p1>p2) swap(p1,p2); printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n", res, p1, p2); } putchar(‘\n‘); } return 0; }
AC代码
#include<cstdio> #include<iostream> #include<cstring> #include<climits> #include<cstdlib> using namespace std; #define N 501 #define inf INT_MAX int n,m,tot,map[N][N],vis[N],dis[N]; int main(){ scanf("%d%d",&n,&m); for(;n+m;){ memset(map,0,sizeof map); memset(vis,0,sizeof vis); memset(dis,0,sizeof dis); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); map[u][v]=map[v][u]=w; } vis[1]=1; for(int i=1;i<=n;i++){ dis[i]=(map[1][i]!=0?map[1][i]:inf); } int t=1; dis[1]=0;//dijkstra for(int i=1;i<n;i++){ int mi=inf;t=1; for(int j=1;j<=n;j++){ if(!vis[j]&&dis[j]<mi){ t=j; mi=dis[j]; } } vis[t]=1; for(int j=1;j<=n;j++){ if(!vis[j]&&map[t][j]!=0&&dis[j]>dis[t]+map[t][j]){ dis[j]=dis[t]+map[t][j]; } } } int p0=1,p1=1,p2=1,gard=1;//开始找关键牌 double res=-inf; for(int i=1;i<=n;i++){ if(res<dis[i]){ res=dis[i]; p0=i; } } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ double x1=1.0*(dis[i]+dis[j]+map[i][j])/2.0; if(map[i][j]&&x1>res){ gard=0; res=x1; p1=i; p2=j; } } } printf("System #%d\n", ++tot); if(gard==1){ printf("The last domino falls after %.1lf seconds, at key domino %d.\n", res, p0); } else{ if(p1>p2) swap(p1,p2); printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n", res, p1, p2); } putchar(‘\n‘); scanf("%d%d",&n,&m); } return 0; }
我醉了~~tyts
标签:
原文地址:http://www.cnblogs.com/shenben/p/5628167.html