poj1062 最短路

来源:互联网 发布:剑三花哥脸型数据 编辑:程序博客网 时间:2024/05/22 10:51

 

如题:http://poj.org/problem?id=1062

昂贵的聘礼
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 38806 Accepted: 11239

Description

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用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 410000 3 22 80003 50001000 2 14 2003000 2 14 20050 2 0

Sample Output

5250

Source

浙江

 

 

 

思路:构造图,顶点输入的N个人。建造图的时候不考虑等级导致的能否交易问题,而在最短路算法中判断。如果当前物品i可以由j物品+cost来交换,那么建立一条i指向j的有项边,权值是cost。然后dijsk,在寻找最短路的时候只有下一个要选的顶点和之前的顶点的等级的差的绝对值小于等于M才可以选,否则按照题目所说,就是间接交易。

注意:可能有人的等级大于酋长。

 

细心的朋友可以发现,虽然代码可以AC,但是dijsktra是贪心的,这一题的解法其实是BUG的,可能因为等级限制导致间接交易的出现导致局部最优的路径不一定是全局最优的路径,因此必须找到所有可能的路径,确保间接交易不会出现,但是肯定是超时的O(n!),只能说出题人出的数据太弱了或者出题人没有想到这个问题或是题目描述不清吧,

如果有真正对的解法希望告知。

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
#define MAXN 105
#define INF 0x0fffffff
#define min(a,b)(a<b?a:b)
#define max(a,b)(a>b?a:b)

struct edge
{
 int to,cost;
 edge(int a,int b):to(a),cost(b){}
};
struct node
{
 int price,degree;
}a[MAXN];
typedef pair<int,int>P; //顶点,最小距离
vector<edge>G[MAXN];
int d[MAXN];
int N,M;
int path[MAXN];
class cmp
{
public:
 bool operator()(P a,P b)
 {
  return a.second>b.second;
 }
};

void dijsktra(int s)
{
 int max_d=a[s].degree;
 int min_d=a[s].degree;
 priority_queue<P,vector<P>,cmp>q;
 int i;
 for(i=0;i<MAXN;i++)
  d[i]=INF;
 d[s]=0;
 q.push(P(s,0));
 while(!q.empty())
 {
  P p=q.top();
  q.pop();
  int v=p.first;
  if(p.second>d[v])
   continue;
  for(i=0;i<G[v].size();i++)
  {
   edge e=G[v][i];
   if(max_d-a[e.to].degree<=M&&a[e.to].degree-min_d<=M)
   if(d[e.to]>d[v]+e.cost&&abs(a[v].degree-a[e.to].degree)<=M)
   {
    d[e.to]=d[v]+e.cost;
    q.push(P(e.to,d[e.to]));
    max_d=max(max_d,a[e.to].degree);
    min_d=min(min_d,a[e.to].degree);
   }
  }
 }
}
int main()
{
 //   freopen("C:\\1.txt","r",stdin);
 cin>>M>>N;
 int i,j;
 for(i=1;i<=N;i++)
 {
  int P,L,X;
  scanf("%d%d%d",&L,&P,&X);
  a[i].price=L;
  a[i].degree=P;
  for(j=1;j<=X;j++)
  {
   int v,cost;
   scanf("%d%d",&v,&cost);
   G[i].push_back(edge(v,cost));
  }
 }
 dijsktra(1);
 int res=INF;
 for(i=1;i<=N;i++)
 {
  d[i]+=a[i].price;
  res=min(res,d[i]);
 }
 printf("%d\n",res);
}

 

 

 

0 0
原创粉丝点击