hdoj 3631 Shortest Path(Floyd思想)

题目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

猜你喜欢

转载自blog.csdn.net/Dear_Jia/article/details/81984598