POJ-1062 昂贵的聘礼 dfs

该题是做最短路专题时的题,但是可惜没有想到如何进行最短路求解。倒是觉得dfs能够得到结果,因为该题对于建立边有严格的条件,递归能够很好的解决这个约束。

每次递归时将当前路径的最低等级和最高等级传递下去,然后再进行判断。这里还要注意判定环的存在。后者没有注意的话会MLE。

 

代码如下:

 

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#define MAXN 105
using namespace std;

int M, N, hash[MAXN];

struct dot
{
    int num, p;
    struct dot *next;
};

struct Node
{
    int p, rank, cnt;
    struct dot *next;
}e[105];

int build(int x, int low, int high)
{
    int fee, Min = e[x].p;
    for (struct dot *ptr = e[x].next; ptr; ptr = ptr->next) {
        
        if ((abs(high - e[ptr->num].rank) <= N) && (abs(low - e[ptr->num].rank) <= N)) {
            if (!hash[ptr->num]) {
                hash[ptr->num] = 1;
                fee = ptr->p + build(ptr->num, min(low, e[ptr->num].rank), max(high, e[ptr->num].rank));
                hash[ptr->num] = 0;
                Min = min(Min, fee);
            }
        }
    }
    return Min;
} 

int main()
{
    struct dot *temp;
    scanf("%d %d", &N, &M);
    for (int i = 1; i <= M; ++i) {
        scanf("%d %d %d", &e[i].p, &e[i].rank, &e[i].cnt);
        e[i].next = NULL;
        for (int j = 1; j <= e[i].cnt; ++j) {
            temp = (struct dot *)malloc(sizeof (struct dot));
            scanf("%d %d", &temp->num, &temp->p);
            temp->next = e[i].next;
            e[i].next = temp;
        }
    }
    hash[1] = 1;
    printf("%d\n", build(1, e[1].rank, e[1].rank)); 
    return 0;
}

 

网上的一份纯c代码,够精简啊!

int g[100][100],a[100][100],pri[100],lvl[100]; 
void main(){ 
    int m,n,i,j,k,t,p,ans,u; 
    scanf("%d %d",&m,&n); 
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            g[i][j]=100000; 
    for(i=0;i<n;i++){ 
        scanf("%d %d %d",&pri[i],&lvl[i],&k); 
        for(j=0;j<k;j++){ 
            scanf("%d %d",&t,&p); 
            g[i][t-1]=p; 
        } 
    } 
    for(i=0;i<n;i++)g[i][i]=0; 
        ans=pri[0]; 
    for(u=0;u<=m;u++){ 
        for(i=0;i<n;i++) {
            for(j=0;j<n;j++){ 
                if(lvl[j]<=lvl[0]+u&&lvl[j]>=lvl[0]-m+u)
                    a[i][j]=g[i][j]; 
                else
                    a[i][j]=100000; 
            } 
        }
        for(k=0;k<n;k++)
            for(i=0;i<n;i++)
                for(j=0;j<n;j++) 
                    if(a[i][k]+a[k][j]<a[i][j])
                        a[i][j]=a[i][k]+a[k][j]; 

        for(i=0;i<n;i++)
            if(ans>a[0][i]+pri[i])
                ans=a[0][i]+pri[i]; 
    } 
    printf("%d\n",ans); 
}

 

 

转载于:https://www.cnblogs.com/Lyush/archive/2012/07/01/2571521.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值