1. 程式人生 > >POJ1062 昂貴的聘禮(最短路)

POJ1062 昂貴的聘禮(最短路)

++ namespace amp name popu 等於 ack 註意 article

說白了就是給你一張圖,每一個點有一個等級限制,在等級限制以內求一條最短路。

構圖方法:首先將原點0連向每個物品相應的編號,那麽邊權為物品的初始價格;假設對於物品j,假設有了物品i,那麽j的優惠價為w,就在i,j之間連一條權值為w的邊。最後枚舉等級的範圍(註意等級的上下差為m,當中包括了酋長的等級,而不是與酋長等級差的絕對值小於等於m QAQ),求到原點到酋長(0號點到1號點)的最短路。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct T
{
	int v;
	int w;
	int next;
}edge[10010];
int head[110],cnt;
void add_edge(int u,int v,int w)
{
	edge[cnt].v = v;
	edge[cnt].w = w;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
int m,n;
int abs(int x)
{
	return x>0?x:-x;
}
int dis[110];
int lv[110];
bool vis[110];
void BFS(int dn,int up)//求最短路
{
	memset(dis,0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	queue<int> myque;
	dis[0] = 0;
	vis[0] = 1;
	myque.push(0);
	while(!myque.empty())
	{
		int u = myque.front();
		myque.pop();
		for(int i = head[u]; i != -1; i = edge[i].next)
		{
			int v = edge[i].v;
			int w = edge[i].w;
			if(!vis[v]&&lv[v] >= dn&&lv[v] <= up)
			{
				if(dis[u] + w < dis[v])
					dis[v] = dis[u] + w;
				myque.push(v);
				vis[v] = 1;
			}
			else if(dis[u] + w < dis[v]&&lv[v] >= dn&&lv[v] <= up)
				dis[v] = dis[u] + w;
		}
	}
}
int main()
{
	memset(head,-1,sizeof head);
	int p,x;
	int y,z;
	scanf("%d%d",&m,&n);
	for(int i = 1; i<= n; i++)
	{
		scanf("%d%d%d",&p,&lv[i],&x);
		add_edge(0,i,p);
		add_edge(i,0,p);
		for(int j = 1; j <= x; j++)
		{
			scanf("%d%d",&y,&z);
			add_edge(y,i,z);
			add_edge(i,y,z);
		}
	}
	int ans = 123456789;
	for(int i = lv[1]-m; i <= lv[1]; i++)//枚舉等級範圍
	{	
		BFS(i,i+m);
		if(dis[1] < ans)
			ans = dis[1];
	}
	printf("%d\n",ans);
}



POJ1062 昂貴的聘禮(最短路)