//目录

昂贵的聘礼,(最短路的应用),Poj(1063)

题目链接:http://poj.org/problem?id=1062

很好的一道中文题。

思路:

把每种替换当做一条边,权重为交易优惠,就是求原点0到物品1的最短路。

这里有限制条件,每个节点还有等级,一条路中任意两个点之间的等级小于li.这里,我只要枚举每个点,以它为标准,删掉那些等级差大于li的点,再进行dijkstra就行了。

 

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define NUM 1005
#define maxint (1<<29)

using namespace std;

int li,n;
int c[NUM][NUM];
int dist[NUM];
int pre[NUM];
int vis[NUM];
int x[NUM];
int lv[NUM];

void dijkstra()
{
    for(int i=1;i<=n;i++)
        dist[i] = c[0][i];
    for(int i=1;i<=n;i++)
    {
        int u = 0;
        int minl = maxint;
        for(int j=1;j<=n;j++)
        {
            if(minl>dist[j]&&!vis[j])
            {
                u = j;
                minl = dist[j];
            }
        }

        if(u == 0)
            break;

        vis[u] = true;

        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&c[u][j]>0&&dist[j]>dist[u]+c[u][j])
                dist[j] = dist[u]+c[u][j];
        }
    }

}
int main()
{
    memset(c,0,sizeof(c));
    memset(lv,0,sizeof(lv));
    memset(dist,maxint,sizeof(dist));
    memset(vis,false,sizeof(vis));

    scanf("%d%d",&li,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&c[0][i],&lv[i],&x[i]);
        for(int j=1;j<=x[i];j++)
        {
            int t,u;
            scanf("%d%d",&t,&u);
            c[t][i] = u;    ///替代品到物品i
        }
    }

    int tmp;
    int minprice = maxint;
    for(int i=1;i<=n;i++)
    {
        int maxlv = lv[i];
        for(int j=1;j<=n;j++)
        {
            if(lv[j]>maxlv||maxlv-lv[j]>li)
                vis[j] = true;
            else vis[j] = false;
        }

        dijkstra();
        tmp = dist[1];

        if(tmp<minprice)
            minprice = tmp;
    }
    printf("%d\n",minprice);

    return 0;
}

 

posted @ 2016-06-23 22:27  小草的大树梦  阅读(276)  评论(0编辑  收藏  举报