hdoj 3631 Shortest Path(Floyd思想)
阿新 • • 發佈:2018-11-07
題目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