POJ 1062 昂贵的聘礼详解最短路变形

POJ上难得一见的中文题……

思路:建立一个以0为源点的地图,那么Map[0][n]的值代表 第n号物品的价值,Map[i][j]代表用 j  替代 i 后,物品j的价值。我们认为酋长的承诺为节点 ‘1’ ,则我们需要做的就是通过一系列操作求出Map[0][1]的最小值,这时可以看出 这是一个最短路问题。题目还规定了,等级高的不会同意与等级低的交换,等级低的亦不会和高于自身m个级别的人交换,所以我们先来个简单的预处理:通过枚举1~N所有点作为最小等级,然后标记出所有非法点。

这样一来就是纯粹的最短路问题了。

#include<stdio.h>
#include<string.h>
#include<cstring>
#include<string>
#include<math.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<cmath>

#define INF 0x3f3f3f3f
#define MAX 1005

using namespace std;

int vis[MAX],dist[MAX],n,m,Map[MAX][MAX];

struct node
{
    int p,l,x;
}a[MAX];

int dij()
{
    int i,j,minn,k;

    for(i=1;i<=n;i++)
        dist[i]=Map[0][i];

    for(i=1;i<n;i++)
    {
        minn=INF;
        for(j=1;j<=n;j++)
        {
            if(!vis[j] && dist[j] < minn)
            {
                minn=dist[j];
                k=j;
            }
        }

        vis[k]=1;

        for(j=1;j<=n;j++)
        {
            if(dist[j] > dist[k] + Map[k][j] && !vis[j])
               dist[j]=Map[k][j]+dist[k];
        }
    }

    return dist[1];
}

int main()
{
    int i,j,x,w;

    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(i=0;i<MAX;i++)
        for(j=0;j<MAX;j++)
        Map[i][j]=INF;

        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&a[i].p,&a[i].l,&a[i].x);

            Map[0][i]=a[i].p;

            for(j=1;j<=a[i].x;j++)
            {
                scanf("%d%d",&x,&w);

                Map[x][i]=w;
            }
        }

        int minn=INF;

        for(i=1;i<=n;i++)//枚举最小等级
        {
            for(j=1;j<=n;j++)
            {
                if(a[i].l < a[j].l || a[i].l-a[j].l > m)
                    vis[j]=1;//标记出非法点
                else
                    vis[j]=0;
            }

            minn=min(dij(),minn);
        }
        printf("%d\n",minn);
    }
    return 0;
}

  

 

posted @ 2016-07-13 22:09  声声醉如兰  阅读(201)  评论(0编辑  收藏  举报