• 昂贵的聘礼 POJ


    昂贵的聘礼 POJ - 1062 

    2018-03-14 14:06:05

    题意:小花想娶部落里的王子 王子的父亲要求一定数量的金币  困窘的小花还有两外一条出路就是得到另外一件东西与王子的父亲交换 以此来减少金币  同理 可以由别的东西来换取现在需要的东西的优惠 另一个限制条件就是 等级相差k的人不能进行交易 即使是间接交易

    思路:建造一棵树 两个节点之间的边权即代表由B事物去换取A事物还需要多少金币  节点用结构体保存 表示这个物品的价格与等级  这样的话 要得到一号节点的王子 就是不断向下搜索 在可以走的条件下(等级限制) 找到尽可能短的路到达一号节点  每一条路径都需要加上末尾节点的值 因为获得最后面的物品也是需要花钱的

    现在附上错误代码 错误代码是按照BFS搜下去 dis[]数组保存的是到达一号节点的距离 然后最后吧所有的节点跑一边 找到最小的dis[]+node[i].mon就好

    错因:我这里的等级限制是由1号节点得来 然后一直使用的 但是在加入一个新的节点到路径上来的时候 后面的节点的等级限制就发生了改变 例如 1号节点的等级是3 k=1 那么等级限制就是2~4 下一个节点的等级是2 满足要求 但是后面路径上的点的等级限制就变成了2~3

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<queue>
    
    using namespace std;
    
    #define inf 0x3f3f3f3f
    
    int k , n;
    
    struct NODE
    {
        int mon;
        int dep;
    }node[110];
    
    int mp[110][110];//记录图
    int dis[110];//记录1号点到其他点的距离
    int vis[110];//是否被加入到最短路中
    
    void init()
    {
        for(int i=1; i<=n; i++)
        {
            dis[i] = inf;
            for(int j=1; j<=n; j++)
            {
                mp[i][j] = inf;
            }
        }
        memset(vis , 0 , sizeof(vis));
    }
    
    void input()
    {
        int num;
        int id , val;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d" , &node[i].mon , &node[i].dep , &num);
            for(int j=1; j<=num; j++)
            {
                scanf("%d%d" , &id , &val);
                mp[i][id] = val;
            }
        }
    }
    
    void solve()
    {
        int l , r;
        int f;
        l = max(0 , node[1].dep-k);
        r = node[1].dep+k;
        dis[1] = 0;
        while( true )
        {
    //        printf("+++++++++++
    ");
            int minn = inf;
            int whe = -1;
            for(int i=1; i<=n; i++)
            {
                if(vis[i]==0 && node[i].dep>=l && node[i].dep<=r && dis[i]<minn)
                {
                    minn = dis[i];
                    whe = i;
                }
            }
            if(whe == -1)
                 break;
            vis[whe] = 1;
    //        printf("%d......
    " , whe);
            for(int i=1; i<=n; i++)
            {
                if(vis[i]==0 && dis[whe]+mp[whe][i]<dis[i])
                {
                    dis[i] = dis[whe]+mp[whe][i];
                }
            }
        }
    }
    
    void ans()
    {
        int minn = inf;
        for(int i=2; i<=n; i++)
        {
            dis[i] += node[i].mon;
            if(vis[i]==1 && dis[i]<minn)
            {
                minn = dis[i];
            }
        }
        if(minn==inf)
            printf("%d
    " , node[1].mon);
        else
            printf("%d
    " , minn);
    }
    
    int main()
    {
        while( scanf("%d%d" , &k , &n) != EOF )
        {
            init();
            input();
            solve();
            ans();
        }
    
        return 0;
    }

    正确代码

    使用DFS来写 每一条路径上不停地更新等级限制

    ///错因  没有更新限制的等级的上下界
    ///此时不能用广搜了 这个想法是不对的 应该用深搜 不断更新上下界
    
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<queue>
    
    using namespace std;
    
    #define inf 1000000000
    
    int k , n;
    
    struct NODE
    {
        int mon;
        int dep;
    } node[110];
    
    int mp[110][110];//记录图
    int dis[110];//记录1号点到其他点的距离
    int vis[110];//是否被加入到最短路中
    int ans;
    int l , r;
    
    void init()
    {
        for(int i=1; i<=n; i++)
        {
            dis[i] = inf;
            for(int j=1; j<=n; j++)
            {
                mp[i][j] = inf;
            }
        }
        memset(vis , 0 , sizeof(vis));
    }
    
    void input()
    {
        int num;
        int id , val;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d" , &node[i].mon , &node[i].dep , &num);
            for(int j=1; j<=num; j++)
            {
                scanf("%d%d" , &id , &val);
                mp[i][id] = val;
            }
        }
    }
    
    void dfs(int num)
    {
        int tmp1 , tmp2;
        for(int i=1; i<=n; i++)
        {
            if(vis[i]==0 && node[i].dep>=l && node[i].dep<=r)
            {
                if((num==1&&mp[1][i]<dis[i]) || dis[num]+mp[num][i]<dis[i])
                {
                    vis[i] = 1;
                    tmp1 = l;
                    tmp2 = r;
                    l = max(l , node[i].dep-k);
                    r = min(r , node[i].dep+k);
                    dis[i] = dis[num]+mp[num][i];
                    dfs(i);
                    vis[i] = 0;
                    l = tmp1;
                    r = tmp2;
                }
            }
        }
        ans = min(ans , dis[num]+node[num].mon);
    }
    
    //void solve()
    //{
    //    int l , r;
    //    int f;
    //    l = max(0 , node[1].dep-k);
    //    r = node[1].dep+k;
    //    dis[1] = 0;
    //    while( true )
    //    {
    ////        printf("+++++++++++
    ");
    //        int minn = inf;
    //        int whe = -1;
    //        for(int i=1; i<=n; i++)
    //        {
    //            if(vis[i]==0 && node[i].dep>=l && node[i].dep<=r && dis[i]<minn)
    //            {
    //                minn = dis[i];
    //                whe = i;
    //            }
    //        }
    //        if(whe == -1)
    //             break;
    //        vis[whe] = 1;
    ////        printf("%d......
    " , whe);
    //        for(int i=1; i<=n; i++)
    //        {
    //            if(vis[i]==0 && dis[whe]+mp[whe][i]<dis[i])
    //            {
    //                dis[i] = dis[whe]+mp[whe][i];
    //            }
    //        }
    //    }
    //}
    
    //void ans()
    //{
    //    int minn = inf;
    //    for(int i=2; i<=n; i++)
    //    {
    //        dis[i] += node[i].mon;
    //        if(vis[i]==1 && dis[i]<minn)
    //        {
    //            minn = dis[i];
    //        }
    //    }
    //    if(minn==inf)
    //        printf("%d
    " , node[1].mon);
    //    else
    //        printf("%d
    " , minn);
    //}
    
    int main()
    {
        while( scanf("%d%d" , &k , &n) != EOF )
        {
            init();
            input();
            ans = node[1].mon;
            l = max(0 , node[1].dep-k);
            r = node[1].dep+k;
            vis[1] = 1;
            dis[1] = 0;
    //        for(int i=2; i<=n; i++)
    //        {
    //            if(node[i].dep>=l && node[i].dep<=r)
    //            {
    //                dis[i] = mp[1][i];
    //            }
    //        }
            dfs(1);
            printf("%d
    ", ans);
    //        ans();
        }
    
        return 0;
    }
  • 相关阅读:
    为什么linux有足够的内存还进行swap?
    vmstat命令的使用
    Windows远程服务器不能复制粘贴
    Windows可以ping通百度,但是用浏览器打不开网页
    java形式参数分别是基本类型和引用类型的调用
    Ubuntu16.04安装Python3.6 和pip
    Python2/3共存,pip2/3共存
    multiprocessing模块
    Python-进程与线程
    鼠标不能动,插上了但没反应
  • 原文地址:https://www.cnblogs.com/Flower-Z/p/8567275.html
Copyright © 2020-2023  润新知