POJ1062 昂贵的聘礼

来源:互联网 发布:云计算产品有哪些 编辑:程序博客网 时间:2024/05/03 02:22

     难得可以看见一道中文题。。。

     题并不是很难,只是有很多细节要处理。建图过程,如果A是B的替代品,那么连一条A到B的边,权值为A的优惠价格。同时设置超级源点,保证图的联通:将超级源点向每一个物体连边,权值为物品的价格,也可以看作超级源点是任意物品的替代品.

     接下来就是一个最短路问题,也就是从超级源点到酋长的最短路。由于等级的存在,需要枚举范围,保证每一种交换方案等级都在规定之内。为了方便,将超级源点的等级设置为酋长的等级,就可以保证最短路过程中超级源点一定不会被舍去。

    Memory: 684K Time: 16MS

#include <iostream>#include <cstdio>#include <string.h>#include <algorithm>#define MAXN 105#define MAXM 10010#define INF 1<<30using namespace std;int level[MAXN],head[MAXN],dis[MAXN],cnt,limit,n;struct EdgeNode{    int to,next,w;}edge[MAXM];void add_edge(int u,int v,int w){     edge[cnt].to=v;edge[cnt].w=w;     edge[cnt].next=head[u];head[u]=cnt++;}int  bellmanford(int low,int up){     int i,j,k;     for(i=0;i<=n;i++)    dis[i]=INF;     dis[0]=0;     for(i=0;i<=n-1;i++)     {          for(j=0;j<=n;j++)          {              if(dis[j]==INF||level[j]<low||level[j]>up)    continue;               //不在等级范围内              for(k=head[j];k!=-1;k=edge[k].next)              {                   int v=edge[k].to;                   if(level[v]<low||level[v]>up)   continue;                   if(dis[v]>dis[j]+edge[k].w)                      dis[v]=dis[j]+edge[k].w;              }          }     }     return dis[1];}int main(){    while(scanf("%d%d",&limit,&n)!=EOF)    {          int p,l,x,ti,pri,minl=INF,maxl=-1;          cnt=0;          memset(head,-1,sizeof(head));          for(int i=1;i<=n;i++)          {                scanf("%d%d%d",&p,&l,&x);                add_edge(0,i,p);                level[i]=l;                minl=min(minl,l);                maxl=max(maxl,l);                for(int j=0;j<x;j++)                {                     scanf("%d%d",&ti,&pri);                     add_edge(ti,i,pri);                }          }          level[0]=level[1];                              //设置超级源点的等级          int ans=INF;          for(int i=minl;i<=maxl-limit;i++)          {                int  low=i,up=low+limit,ans1=INF;                if(low<=level[1]&&up>=level[1])                         ans1=bellmanford(low,up);                if(ans1<ans)   ans=ans1;          }          if(maxl-limit<minl)    ans=bellmanford(minl,maxl);                //如果最大等级与最小等级的差比限制小,就可以直接求解          printf("%d\n",ans);    }    return 0;}

         

0 0