題解[AHOI2002]哈利·波特與魔法石
阿新 • • 發佈:2019-02-10
pty problem printf {0} main ret 建立 題解 一道
題目傳送門
這是一道很經典的最短路問題
因為數據範圍較小,所以不用鄰接表的SPFA也不會MLE
#include<bits/stdc++.h> using namespace std; int a[120][120]; //a[i][j]代表從i到j的路程(-1表示沒路) int h[8] = {0,2,6,4,8,6,10,14}; //h代表每種地形所需時間 queue<int> q; //隊列 int s,e;//起點和終點 int dis[120]; //dis[i]代表點i到起點的最短時間 bool used[120] = {0}; //防止元素重復入隊 int main(){ memset(a,-1,sizeof(a)); memset(dis,-1,sizeof(dis)); bool flag; for(int i = 1;i<=7;i++){ scanf("%d",&flag); if(flag==1)h[i]/=2; }//如果有魔法石則時間減半 scanf("%d%d",&s,&e); int n; scanf("%d",&n); int ai,bi,ti; for(int i = 1;i<=n;i++){ scanf("%d%d%d",&ai,&bi,&ti); a[ai][bi] = h[ti]; a[bi][ai] = h[ti]; //註意是無向圖,要建立雙向邊(如果不建立雙向邊只有20分,我為此提交了4遍才過) } q.push(s); //起點入隊 dis[s] = 0; while(!q.empty()){ // 裸的SPFA int nw = q.front(); for(int i = 1;i<=101;i++){ if(a[nw][i]==-1)continue; int rd = dis[nw]+a[nw][i];//rd為經過nw到a的最短時間 if(dis[i]==-1){ //如果這個點是第一次搜索到 dis[i] = rd; q.push(i); used[i] = 1; }else{ //否則比較dis[i]和rd大小 if(dis[i]<=rd)continue; dis[i] = rd; if(!used[i]){ q.push(i); used[i] = 1; } } } q.pop(); used[nw] = 0; } printf("%d",dis[e]); //輸出終點到起點的最短時間 return 0; }
題解[AHOI2002]哈利·波特與魔法石