题目地址:http://acm.hdu.edu.cn/showPRoblem.php?pid=3631
思路:Floyd,对于已求出最短路的图,若增加一点k及相应的边,则只需将k当做中间节点更新点u与点v的距离即可。因此,每增加一个标记点时,则将标记点当做中间节点更新最短路径,由于点数只有300,时间上可以承受。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int maxn=300+50;const int INF=0x3f3f3f3f;int n,m,q;int flag[maxn];LL g[maxn][maxn];void Floyd(int k){ for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { g[i][j]=min(g[i][j],g[i][k]+g[k][j]); } }}void init(){ for(int i=0; i<n; i++) { g[i][i]=0; for(int j=0; j<n; j++) if(i!=j) g[i][j]=INF; } memset(flag,0,sizeof(flag));}int main(){ int cas=0; while(scanf("%d%d%d",&n,&m,&q)!=EOF&&n) { cas++; if(cas!=1) printf("/n"); printf("Case %d:/n",cas); init(); for(int i=0; i<m; i++) { LL w; int x,y; scanf("%d%d%lld",&x,&y,&w); g[x][y]=min(g[x][y],w); } for(int i=0; i<q; i++) { int cmd,x,y; scanf("%d",&cmd); if(cmd==0) { scanf("%d",&x); if(flag[x]) printf("ERROR! At point %d/n",x); else { Floyd(x); flag[x]=1; } } else { scanf("%d%d",&x,&y); if(!flag[x]||!flag[y]) printf("ERROR! At path %d to %d/n",x,y); else { if(g[x][y]>=INF) printf("No such path/n"); else printf("%lld/n",g[x][y]); } } } } return 0;}
新闻热点
疑难解答