POJ 1062昂贵的聘礼 (建图+dijkstra)

题目地址: http://poj.org/problem?id=1062

开始用DFS写 , 莫名其妙的MLE,明明没有超,就这样纠结, 而且咩有纠结出来。。。一定要弄出来(DFS MLE代码http://paste.ubuntu.com/5961195/

之后用最短路写, 主要是处理 等级的限制。 用到枚举 ,枚举以酋长的地位为其中的值,以m为范围,求出每次可以可能 到达的等级 记录为within[],松弛要做出些微的改变

之后分别dijkstra, 求出最小的

开始还是WA了几次, 因为 忘了预处理 也要 考虑 within[]  之后就A掉了, 一直很纠结于DFS写法 。。

这题 做的时间很长, 要快一点了!!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define INT_MAX 0x3f3f3f3f
#define max(a,b) (a)>(b)? (a):(b)
#define min(a,b) (a)>(b)? (b):(a)
int m,n;
struct node
{
    int p,l,x;
}nu[105];
int map[105][105];
int used[105];
int within[105];
int dis[105];
int dijk(int v)
{
    int i,j,k;
  /*  for(i=0;i<=n;i++)
    {
        if(within[i])
        dis[i]=map[v][i];
        else dis[i]=INT_MAX;
        used[i]=0;
    }
    used[v]=1;
    dis[v]=0;*/
    for(i=0;i<=n;i++) dis[i]=INT_MAX;
    memset(used,0,sizeof(used));
    dis[v]=0;
    for(i=1;i<=n-1;i++)
    {
        int mi=INT_MAX;
        int arr=v;
        for(j=1;j<=n;j++)
        {
            if(!used[j] && within[j]&& mi>dis[j])//
            {
                mi=dis[j];
                arr=j;
            }
        }
        used[arr]=1;
        for(k=1;k<=n;k++)
        {
            if( !used[k] &&within[k] && dis[arr]+map[arr][k]<dis[k])//
            {
                dis[k]=dis[arr]+map[arr][k];
            }
        }
    }
    int mii=INT_MAX;
    for(i=1;i<=n;i++)
    {
        dis[i]+=nu[i].p;
        if(dis[i]<mii) mii=dis[i];
    }
    return mii;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int i,j,k;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(i=0;i<=n;i++)
        {
            for(j=0;j<=n;j++)
            {
                map[i][j]=INT_MAX;
                if(i==j) map[i][j]=0;
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&nu[i].p,&nu[i].l,&nu[i].x);
            for(j=1;j<=nu[i].x;j++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                map[i][a]=b;
            }
        }
        //within
        int x,y;
        int ans=INT_MAX;
        for(x=nu[1].l-m;x<=nu[1].l;x++)
        {
            y=x+m;
            memset(within,0,sizeof(within));
            for(i=1;i<=n;i++)
            {
                if(nu[i].l>=x && nu[i].l<=y)
                {
                    within[i]=1;
                }
            }
            int mm=dijk(1);
            ans=min(ans,mm);
        }
        printf("%d\n",ans);
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值