建圖的思想codevs1364尋寶

題目描述 Description
傳說很遙遠的藏寶樓頂層藏着誘人的寶藏。小明歷盡千辛萬苦終於
找到傳說中的這個藏寶樓,藏寶樓的門口豎着一個木板,上面寫有幾
個大字,尋寶說明書。說明書的內容如下:
藏寶樓共有 N+1 層,最上面一層是頂層,頂層有一個房間裏面藏
着寶藏,每一層有 M 個房間。一開始,你可以從第一層的任何一個
房間進入,每個房間都有一個木牌,上面有一個數字,你可以順時針
或逆時針走,你每進入一個房間,就將房間內的數字進行累加,寶箱
的密碼就是到頂層可以得到的最小值。
請幫助小明算出這個打開寶箱的密鑰。

輸入描述 Input Description
第一行 2 個整數 N 和 M,之間用一個空格隔開。N 表示除了頂層
外藏寶樓共 N 層樓,M 表示除頂層外每層樓有 M 個房間。

接下來 N*M 行,每行兩個整數之間用一個空格隔開,每行描述一
個房間內的情況


其中第(i-1)*M+j 行表示第 i 層 j-1 號房間的情況
(i=1, 2, …,N j=1, 2,… ,M)。
第一個整數表示該房間是否有樓梯通往上一層,0 表示沒有,1 表
示有,第二個整數表示指示牌上的數字。注意,從 j 號房間的樓梯爬
到上一層到達的房間一定也是 j 號房間。


輸出描述 Output Description
輸出只有一行,一個整數,表示打開寶箱的密鑰,若無可通往頂層
的路,輸出-1。


樣例輸入 Sample Input
1  2
1  1000
0  1


樣例輸出 Sample Output
1000


數據範圍及提示 Data Size & Hint

對於 50%的數據,N≤20 M≤20

對於100%的數據,N≤60 M≤60


注意:要有建圖的思想,每層是個環,房子是桶形的

我把點權寫成了邊權,有點多此一舉


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
#define INF 1000000000
#define MAXN 20000
#define MAXM 20000
int n,m;
struct node {
	int u,v,w,next;
} E[MAXM];
int head[MAXM],tot;
void add(int u,int v,int w) {
	E[++tot].u=u,E[tot].v=v,E[tot].w=w,E[tot].next=head[u],head[u]=tot;
}
int d[MAXN];
void dijkstra(int s,int t) {
	for(int i=0; i<=n*m+1; i++)d[i]=INF;
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
	d[s]=0,q.push(make_pair(d[s],s));
	while(!q.empty()) {
		int now=q.top().second;q.pop();
		for(int i=head[now]; i; i=E[i].next) {
			int v=E[i].v;
			if(d[v]>d[now]+E[i].w) {
				d[v]=d[now]+E[i].w;
				q.push(make_pair(d[v],v));
			}
		}
	}
	d[t]==INF?printf("-1\n"):printf("%d\n",d[t]);
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=m; i++)add(0,i,0);
	for(int i=1; i<n; i++)
		for(int j=1; j<=m; j++) {
			int flag,u,w;
			scanf("%d%d",&flag,&w);
			u=(i-1)*m+j;
			if(flag)add(u,u+m,w);
			if(j!=m)add(u,u+1,w);
			else    add(u,(i-1)*m+1,w);
			if(j!=1)add(u,u-1,w);
			else    add(u,i*m,w);
		}
	for(int i=1; i<=m; i++) {
		int flag,u,w;
		scanf("%d%d",&flag,&w);
		u=(n-1)*m+i;
		if(flag)add(u,n*m+1,w);
		if(i!=m)add(u,u+1,w);
		else    add(u,(i-1)*m+1,w);
		if(i!=1)add(u,u-1,w);
		else    add(u,i*m,w);
	}
	dijkstra(0,n*m+1);
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章