POJ 1062 昂贵的聘礼(Dijkstra)
http://poj.org/problem?id=1062
题意: 年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。
Input
输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠价格"。
Output
输出最少需要的金币数。
Sample Input
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
Sample Output
5250
分析:
现在我们假设没有等级限制,且有A,B,C共3种商品且A,B,C的原价分别为10000,9000,8000且A可以由B物品加上优惠价7000换取,A还可以由C物品加上优惠价1000换取. 我们在纸上把这个图画出来,然后添加一个0号节点.
从0号节点到A,B,C的有向边花费为A,B,C 3物品直接购买(不用物品+优惠价)的价格.比如从0到A花费10000.
然后比如A物品 可以用B物品+7000来换取,那么从B到A物品有一条有向边,花费为7000.从C到A有一条花费1000的有向边.
其实上面建立的图从0号节点到A或B或C的一条路的总花费就是购买A,B,C物品的一种可能总花费了.
那么我们想要购买A物品的最小花费是多少呢? 明显可以看出从0号节点到A物品的最短路径就是最小花费了.
上面我们已经解决了本题的一半问题,还有一半问题是等级限制的问题.
对于等级限制,我们枚举n个物品主人等等级x,然后我们算一次最短路径,但是在Dijkstra中我们只遍历由[x,x+m]等级范围的点构成的边.
最终我们求出d[1](从0号点到1号点的最短距离)即最小开销.
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define INF 1e8
const int maxn= 100+10;
int n,M; //物品总数,等级差距
int level[maxn];
/*******************Dijkstra******************************/
struct Edge
{
int from,to,dist;
Edge(){}
Edge(int from,int to,int dist):from(from),to(to),dist(dist){}
};
struct HeapNode
{
int d,u;
HeapNode(){}
HeapNode(int d,int u):d(d),u(u){}
bool operator < (const HeapNode & rhs)const
{
return d>rhs.d;
}
};
struct Dijkstra
{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];
void init(int n)
{
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist)
{
edges.push_back(Edge(from,to,dist));
m=edges.size();
G[from].push_back(m-1);
}
int dijkstra(int min_level)
{
priority_queue<HeapNode> Q;
for(int i=0;i<n;i++) d[i]=INF;
d[0]=0;
memset(done,0,sizeof(done));
Q.push(HeapNode(0,0));
while(!Q.empty())
{
HeapNode x= Q.top(); Q.pop();
int u=x.u;
if(done[u]) continue;
done[u]=true;
for(int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if( level[e.to]>=min_level && level[e.to]<=min_level+M )
if ((u==0)||( level[u]>=min_level && level[u]<=min_level+M) )
{
if(d[e.to] > d[u]+e.dist)
{
d[e.to] = d[u]+e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode(d[e.to],e.to));
}
}
}
}
return d[1];
}
}DJ;
/*******************Dijkstra******************************/
int main()
{
while(scanf("%d%d",&M,&n)==2)
{
DJ.init(n+1);
for(int i=1;i<=n;i++)
{
int p,x;
scanf("%d%d%d",&p,&level[i],&x);
DJ.AddEdge(0,i,p);
while(x--)
{
int t,v;
scanf("%d%d",&t,&v);
DJ.AddEdge(t,i,v);
}
}
int min_v = INF;
for(int i=1;i<=n;i++)
{
min_v = min(min_v,DJ.dijkstra(level[i]));
}
printf("%d\n",min_v);
}
return 0;
}
分享到:
相关推荐
poj 1062 昂贵的聘礼 代码 单源最短路径的Dijkstra算法
业余爱好。所以,算法不一定好,CODING也不一定佳,效率不一定高,只是能通过online judge而已。
北大POJ1062-Expensive dowry【dijkstra】 解题报告+AC代码
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
dijkstra 算法 需要考虑重边.........
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240) (3)最小生成树算法(prim,kruskal) (poj1789,poj2485,poj1258,poj3026) (4)拓扑排序 (poj1094) (5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020) ...
Net<br>Pku acm 3278 Catch That Cow<br>Pku acm 2253 Frogger<br>Pku acm 1062 昂贵的聘礼 Pku acm 1125 Stockbroker Grapevine Pku acm 1611 The Suspects Pku acm 2492 A Bug's Life 更多请访问:...
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ1159-Palindrome 解题报告+AC代码
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj分类poj分类poj分类poj分类
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
北大POJ2002-Squares 解题报告+AC代码
POJ1048,加强版的约瑟夫问题 难度中等
POJ1083的代码,POJ1083的代码,POJ1083的代码