(poj 1062 昂贵的聘礼)<最短路建模>

来源:互联网 发布:微分销java源码 编辑:程序博客网 时间:2024/06/06 13:05

传送门

如果虚拟一个源点s,题目就转化为求s到点1的最短路
把每个物品向s连一条边权为自己价格的边
同时如果拥有B可以使A优惠到C元,连边B到A,边权为C
他可以交易的人群的范围是国王的等级±m,枚举就好了
注意国王的等级不一定最高
这种国王的女儿你娶她干嘛?因为爱情(手动划掉)

Code

// by spli#include<cstring>#include<iostream>#include<algorithm>#include<cstdio>#include<queue>using namespace std;const int N=110;int m,n;struct node{    int to,nxt,val;}e[N*N*2];int head[N],cnt;int lev[N];int dis[N];bool vis[N];queue<int>q;int ans=0x3f3f3f3f;void add(int f,int t,int v){    cnt++;    e[cnt]=(node){t,head[f],v};    head[f]=cnt;}void spfa(int d){    memset(dis,0x3f3f3f3f,sizeof(dis));    q.push(0);dis[0]=0;vis[0]=1;    while(!q.empty()){        int u=q.front();        q.pop();        vis[u]=0;        for(int i=head[u];i!=-1;i=e[i].nxt){            int v=e[i].to;            if(lev[v]-m<=d&&lev[v]>=d&&dis[v]>dis[u]+e[i].val){                dis[v]=dis[u]+e[i].val;                if(!vis[v]){                    vis[v]=1;                    q.push(v);                }            }        }    }    ans=min(ans,dis[1]);}int main(){    scanf("%d%d",&m,&n);    memset(head,-1,sizeof(head));    int p,x,y,c;    for(int i=1;i<=n;++i){        scanf("%d%d%d",&p,&lev[i],&x);        add(0,i,p);        for(int j=1;j<=x;++j){            scanf("%d%d",&y,&c);            add(y,i,c);        }    }    for(int i=lev[1];i>=lev[1]-m;--i) spfa(i);    cout<<ans;    return 0;}
原创粉丝点击