• poj1062昂贵的聘礼


    这个题目我最開始看题目看了半天,看不懂。。

    可是通过看例子及答案最终看懂了。

    。。

    首先先解决等级的关系。

    。假设等级越界。则不能交换。。所以原本等级的界限是

    [rank[1]-m,rank[1]+m],可是这个边界里面会出现等级仅仅差大于m。所以等级的区间应该是

    [rank[1]-m,rank[1]],[rank[1]-m+1,rank[1]+1]............等等。所以一直枚举到 [rank[1],rank[1]+m]..所以先通过枚举得到能够交换的点。

    。然后就是题目的意思了。

    我理解的优惠相当于是分解。

    。。比方假设得到1号物品须要得到2号物品和8000金币。不就相当于1号到2号号为单向路劲,权值为8000.。

    。求各个点到1号点的最短路加上这个点的价值。。

    如图所看到的。

    。。

                    1(10000)---------->2(1000)--------->4(50)

                     |              8000                  200    |

                     |--------------------->3(3000)----------|

                        5000                             200

    绘图之后一目了然。。。

    然后运用dijkstra解决。

    。。

    。。

    。。

    希望各位指正我的想法。。

    代码例如以下:

    #include<cstdio>
    #include<cstring>
    #define INF 0x3f3f3f3f
    const int maxn=100+10;
    int m,n;
    int vis[maxn],dis[maxn],e[maxn][maxn];
    int withtin[maxn],value[maxn],ranki[maxn];
    
    int dijkstra()
    {
        int tmp,now,i,j;
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        dis[1]=0;
        for(i=1;i<=n;i++)
        {
            tmp=INF;
            for(j=1;j<=n;j++)
            {
                if(!vis[j]&&withtin[j]&&dis[j]<tmp)
                {
                    tmp=dis[j];
                    now=j;
                }
            }
            vis[now]=1;
            for(j=1;j<=n;j++)
            {
                if(!vis[j]&&withtin[j]&&dis[j]>dis[now]+e[now][j])
                    dis[j]=dis[now]+e[now][j];
            }
        }
        tmp=INF;
        for(i=1;i<=n;i++)
        {
            if(dis[i]+value[i]<tmp)
                tmp=dis[i]+value[i];
        }
        return tmp;
    }
    
    
    int main()
    {
        int i,j,t,cost;
        int p,l,x,val,min_cost;
        while(scanf("%d%d",&m,&n)!=EOF)
        {
            memset(e,0x3f,sizeof(e));
            for(i=1;i<=n;i++)
                 for(j=1;j<=n;j++)
                {
                    if(i==j)
                    e[i][j]=0;
                }
            for(i=1;i<=n;i++)
            {
                scanf("%d%d%d",&value[i],&ranki[i],&x);
                for(j=1;j<=x;j++)
                {
                    scanf("%d%d",&t,&val);
                    e[i][t]=val;
                }
            }
            min_cost=INF;
            for(i=0;i<=m;i++)
            {
                memset(withtin,0,sizeof(withtin));
                for(j=1;j<=n;j++)
                {
                    if(ranki[j]>=ranki[1]-m+i&&ranki[j]<=ranki[1]+i)
                        withtin[j]=1;
                }
                cost=dijkstra();
                 if(cost<min_cost)
                    min_cost=cost;
            }
            printf("%d
    ",min_cost);
        }
    }
    


                          

  • 相关阅读:
    IntentService使用以及源码分析
    Android HandlerThread源码解析
    Android Handler消息机制源码解析
    Gradle技术之四
    Android EditText实现小数点后几位的终级方案
    Gradle系列之三 Gradle概述以及生命周期
    Gradle系列之二 Groovy对文件的操作
    Gradle系列之一 Groovy语法精讲
    Context源码分析
    用EXCLE群发outlook邮件
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6821181.html
Copyright © 2020-2023  润新知