1. 程式人生 > >0924-安徽省選 2002-哈利●波特與魔法石

0924-安徽省選 2002-哈利●波特與魔法石

題目描述

某天,哈利•波特准備去拯救 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;
}