SDUT2155 Emergency(第一届省赛题)(弗洛伊德算法)
原创
©著作权归作者所有:来自51CTO博客作者wx5915393277dca的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2155
题意大概一个地方所有城市被侵占
开始解放每个城市,一个人要从解放的城市到达另一个解放的城市,所有需要求所有两个城市的最短路径
N个节点 M个边 Q个操作
接下来M行 每行表示一条高速公路连接x,y 长度为z
接下来Q个操作 操作分两种
0 表示解放x
1 表示 问能否从x到y
输出:
0时 如果0 x 这个x在之前就已经被解放 就输出“City 0 or 2 is not available”(0 2 之前有了0 2)
1时 x或y没被解放过 就输出“City 0 or 2 is not available”
1时 x,y之间没路 输出“No such path.”
1时 满足上面两个条件输出“3“路径长度
解题:知道Floyd的就很好做,对每个新添加的点进行弗洛伊德计算最短路径就可以。
用了一个vis数组记录有没有被recaptured
不知道的做不出来了吧,面很广~
#include<iostream>
#include<cmath>
#include<string.h>
#include<stdio.h>
#define INT_MAX 100000
using namespace std;
int n,m,q;
int map[310][310],vis[310];
void floyd(int k){
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if((map[i][k]!=INT_MAX) && (map[k][j]!=INT_MAX))
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}
}
void init()
{
int i,j;
for(i=0;i<310;i++){
for(j=0;j<310;j++)
map[i][j]=INT_MAX;
map[i][i]=0;
}
}
int main()
{
int i,j,k,l,x,y,z,d,c=0;
while(cin>>n>>m>>q&&(n||m||q))
{
init();
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++){
cin>>x>>y>>z;
if(map[x][y]>z)
map[x][y]=z;
}
printf("Case %d:\n",++c);
for(j=0;j<q;j++){
cin>>d;
if(!d){
cin>>x;
if(!vis[x]){
vis[x]=1;
floyd(x);
}
else printf("City %d is already recaptured.\n",x);
}
else{
cin>>x>>y;
if(!vis[x]||!vis[y])
printf("City %d or %d is not available.\n",x,y);
else if(map[x][y]==INT_MAX)
cout<<"No such path."<<endl;
else cout<<map[x][y]<<endl;
}
}
cout<<endl;
}
return 0;
}