poj 1062(Kuangbin最短路专题M题)

来源:互联网 发布:windows定时启动程序 编辑:程序博客网 时间:2024/05/18 03:23
/**输入:输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠后的价格"。限制条件:所有参与交换的物品主人等级之间差距不超过m 输出:最少需要的金币数。解法:构造源点0向每个物品连一条边,dist为物品本身的价格。枚举哪个物品作为等级最高的物品,限制参与交换的物品(方法为,若某一物品等级超过了等级最高的物品,或者等级过低,把done设成true,不参与dijkstra的运算)求出最小的金币数。**/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <cmath>const int inf=1<<27;const int maxn=105;using namespace std;struct Edge{    int from,to,dist;    Edge(int a,int b,int c)    {        from=a;        to=b;        dist=c;    }};struct node{    int status,price;}s[maxn];struct HeapNode{    int d,u;    bool operator < (const HeapNode &rhs) const    {        return d > rhs.d;    }};struct Dijkstra{    int n,m;    int d[maxn];    bool done[maxn];    vector<Edge> edges;    vector<int> G[maxn];    void init(int n)    {        this->n=n;        for(int i=0;i<n;i++) G[i].clear();        edges.clear();    }    void add_edge(int from,int to,int dist)    {        edges.push_back((Edge){from,to,dist});        m=edges.size();        G[from].push_back(m-1);    }    void dijkstra(int ss)    {        priority_queue<HeapNode> q;        for(int i=0;i<n;i++) d[i]=inf;        d[ss]=0;        q.push((HeapNode){0,ss});        while(!q.empty())        {            HeapNode x=q.top();            int u=x.u;            q.pop();            if(done[u])continue;            done[u]=true;            for(int i=0;i<G[u].size();i++)            {                Edge &e=edges[G[u][i]];                if(!done[e.to] && d[e.to]>d[u]+e.dist)                {                    d[e.to]=d[u]+e.dist;                    q.push((HeapNode){d[e.to],e.to});                }            }        }    }};int main(){    int m,n,i,x,j,num,cut,maxlv;    Dijkstra solver;    scanf("%d%d",&m,&n);    solver.init(n+1);    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&s[i].price,&s[i].status,&x);        for(j=0;j<x;j++)        {            scanf("%d%d",&num,&cut);            solver.add_edge(num,i,cut);        }        solver.add_edge(0,i,s[i].price);    }    int ans=s[1].price;    for(i=1;i<=n;i++)    {        maxlv=s[i].status;        for(j=1;j<=n;j++)        {            if(s[j].status>maxlv || maxlv-s[j].status>m) solver.done[j]=true;            else solver.done[j]=false;        }        solver.done[0]=false;        solver.dijkstra(0);        ans=min(ans,solver.d[1]);    }    printf("%d\n",ans);    return 0;}

0 0