1. 程式人生 > >hdoj 3631 Shortest Path(Floyd思想)

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