0924-安徽省選 2002-哈利●波特與魔法石
阿新 • • 發佈:2018-12-11
題目描述
某天,哈利•波特准備去拯救 Super Swamuel 星球上的生靈。該星球上有七種不同的地形,依次分別是:石子路、森林、草地、山地、雪地、沼澤和沙漠。分別用數字 1~7 來表示,穿越這七種地形需要的時間分別用 h1~h7 表示。
任意兩個城市之間都存在至少一條通路,而且任意兩個直通的城市之間都只存在一種地形。哈利•波特穿越地形 u 所需要的時間與該地形的區域大小無關,而與地形 u 的區域中是否有魔法石有關。如果地形 u 的區域中沒有魔法石,哈利•波特需要花費 hu 的時間能穿越該地區;如果他有魔法石,則只要花一半的時間(hu/2)就能穿越地形 u。這裡 hu/2 用整除法。
已知沒有魔法石的情況下穿越七種地形需要的時間分別如下表格:
地形名稱 | 石子路 | 森林 | 草地 | 山地 | 雪地 | 沼澤 | 沙漠 |
地形編號(i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
穿越時間(hi) | 2 | 6 | 4 | 8 | 6 | 10 | 14 |
哈利•波特將從城市 i 出發到城市 j 去伸張正義,請你幫他尋找出最快的路線。
輸入格式
第一行有七個整數 s1~s7 ,分別表示七種地形中是否有魔法石,su=0 表示地形 u 的區域中沒有魔法石;su=1 表示地形 u 的區域中有魔法石。su ∈{0,1} 第二行有兩個正整數,分別是起點 i 的編號和終點 j 的編號。 第三行有一個正整數 m(m≤10000),表示以下有 m 對直接相連的城市。 隨後 m 行,每行三個正整數 i,j,k,分別是城市 i 與城市 j 之間連通,這兩個城市之間的地形是 k,其中:0<i,j≤1000,k∈{1,2,3,4,5,6,7} ,地形編號意義請參考“題目描述”中的表格。
輸出格式
輸出一個整數,即穿越起點城市 i 與終點城市 j 之間的地形需要的最短時間。
樣例資料 1
輸入
0 1 0 0 0 0 0 1 4 4 1 2 1 1 3 1 2 4 2 3 4 3
輸出
5
備註
【樣例說明】 從路徑 1→2→4 穿越,需要的最短時間是:2+(6/2)=5
分析
就是一個最短路的板子題,我這裡用的是迪傑斯特拉+堆優化
程式碼
#include<bits/stdc++.h> #define in read() #define N 1009 #define M 20009 using namespace std; inline int read(){ char ch;int res=0; while((ch=getchar())<'0'||ch>'9'); while(ch>='0'&&ch<='9'){ res=(res<<3)+(res<<1)+ch-'0'; ch=getchar(); } return res; } int h[8]={2,6,4,8,6,10,14}; int head[N],nxt[M],w[M],to[M],cnt=0; int sta,end,m; void add(int x,int y,int z){ nxt[++cnt]=head[x];head[x]=cnt;to[cnt]=y;w[cnt]=z; nxt[++cnt]=head[y];head[y]=cnt;to[cnt]=x;w[cnt]=z; } priority_queue<pair<int,int> > q; int dis[1009]; void dij(int st){//最短路板子 memset(dis,0x3f3f3f3f,sizeof(dis)); q.push(make_pair(st,0));dis[st]=0; while(!q.empty()){ int u=q.top().first; int d=q.top().second; d=-d; q.pop(); for(int e=head[u];e;e=nxt[e]){ int v=to[e]; if(dis[v]>d+w[e]){ dis[v]=d+w[e]; q.push(make_pair(v,-dis[v]));//存負的,大根堆變小 } } } } int main(){ int i,j,k,x,y,z; for(i=0;i<7;++i){ k=in; if(k==1) h[i]/=2; } sta=in;end=in;m=in; for(i=1;i<=m;++i){ x=in;y=in;z=in;//讀入的z是從1~7,而我是用0~6來儲存的 add(x,y,h[z-1]); } dij(sta); printf("%d",dis[end]); return 0; }