题目source:http://acm.hdu.edu.cn/showproblem.php?pid=3631
题目大意:给一些点,求两点之间的最短路径,但是只能通过被标记的点
有两种操作,0的话标记点,1的话求最短路径
解题思路:用Floyd算法,但是不是直接套模板,而是利用Floyd算法的思想
解题(时间复杂度为O(n^2)),Floyd算法的主要思想是通过加点进行松弛操作,
然后找到两个点之间的最小值
#include<stdio.h>
#include<string.h>
#define maxn 0x3f3f3f3f
int visit[310];//记录点是否被标记过,1表示标记过,0表示没有标记过
long long map[310][310];
int N;//邻接矩阵记录两点之间的关系
int Floyd(int k){//不是平常的Floyd模板,而是利用Floyd思想,直接进行松弛操作
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(map[i][j]>map[i][k]+map[k][j]){
map[i][j]=map[i][k]+map[k][j];
}
}
}
}
int main(){
int M,Q,x,y,num;
long long c;
int count=1;
while(scanf("%d %d %d",&N,&M,&Q)!=EOF){
if(!N&&!M&&!Q)
break;
memset(visit,0,sizeof(visit));//假设所有的点都还没被标记
//memset(map,maxn,sizeof(map));
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
map[i][j]=(i==j)?0:maxn;
}
}
//map[i][i]=0;
if(count!=1)
printf("\n");//There is a blank line between two consecutive test cases.
printf("Case %d:\n",count++);
for(int i=0;i<M;i++){
scanf("%d %d %lld",&x,&y,&c);
if(map[x][y]>c){//去重
map[x][y]=c;
}
}
for(int i=0;i<Q;i++){
scanf("%d",&num);
if(num==0){
scanf("%d",&x);
if(visit[x]==1){
printf("ERROR! At point %d\n",x);
}
else{
visit[x]=1;
Floyd(x);//以x为插入点进行松弛操作,更新各顶点之间的最短路径
}
}
else{
scanf("%d %d",&x,&y);
if(!visit[x]||!visit[y]){
printf("ERROR! At path %d to %d\n",x,y);
}
else{
if(map[x][y]==maxn){
printf("No such path\n");
}
else{
printf("%lld\n",map[x][y]);
}
}
}
}
}
return 0;
}
提交WA了,原因竟然是初始化问题。。。这里初始化时候不能用memset,因为memset是以字节型为单位复制的,详见https://blog.csdn.net/Dear_Jia/article/details/81984398