zoukankan      html  css  js  c++  java
  • POJ 1062 昂贵的聘礼

      题意:每个物品看成一个节点,酋长的允诺也看作一个物品, 如果一个物品加上金币可以交换另一个物品,则这两个节点之间有边,权值为金币数,求第一个节点到所有节点的最短路。
    因为有等级限制,所以枚举每个点作为最低等级,选取符合所有符合等级限制的点

      最短路问题,不过因为存在着等级的差异所以需要枚举一下。本题的思路就是对冒险者的等级进行枚举,也就是说冒险者只能和在他等级以上的人进行交易。这样枚举的好处是能够把所有的情况都考虑进去。有一点需要注意:酋长的等级不一定是最高的

      构图时要注意的是,酉长的承诺不是 最初的源点,它是一个目标点,也就是说点到点的指向方向是由 无替代品的点 逐渐指向到 酉长的承诺1点,题意说明的是一个回溯的过程,因此可以定义一个最初的源点0点,它到其他各点的权值就是每个物品的原价,而点A到点B的权值 就是 物品B在有第A号替代品情况下的优惠价

      先回顾一下最短路算法:最短路知识点总结(Dijkstra,Floyd,SPFA,Bellman-Ford)

      本题我用的是dijkstra算法:

     1 //昂贵的聘礼
     2 #include <iostream>
     3 #include<algorithm>
     4 #include<string>
     5 #include<string.h>
     6 #include<stdio.h>
     7 using namespace std;
     8 #define inf 0x7fffffff
     9 int m,n;//地位等级限制,物品总数
    10 int price[101][101];//物品i在有第t号替代品情况下的优惠价pricr[t][i],当t=0时说明i无替代品,此时为原价
    11 int lv[101];//i号物品主人的等级
    12 int sum[101];//i号物品的替代品总数
    13 int dist[101];//相当于每件物品的原价
    14 bool bools[101];//标记物品是否被访问
    15 int dijkstra()
    16 {
    17     int node,minDist;
    18     for(int i=1;i<=n;i++)
    19         dist[i]=price[0][i];
    20     for(int i=1;i<=n;i++)
    21     {
    22         node=0;
    23         minDist=inf;
    24         for(int j=1;j<=n;j++)
    25         {
    26             if(!bools[j]&&minDist>dist[j])
    27             {
    28                 minDist=dist[j];
    29                 node=j;
    30             }
    31         }
    32         if(node==0)
    33         {
    34             break;
    35         }
    36         bools[node]=true;
    37         //松弛
    38         for(int j=1;j<=n;j++)
    39         {
    40             if(!bools[j]&&price[node][j]>0&&dist[j]>dist[node]+price[node][j])
    41                 dist[j]=dist[node]+price[node][j];
    42         }
    43     }
    44     return dist[1];
    45 }
    46 int main()
    47 {
    48     memset(price,0,sizeof(price));
    49     memset(lv,0,sizeof(lv));
    50     memset(dist,inf,sizeof(dist));
    51     memset(bools,false,sizeof(bool));
    52     scanf("%d%d",&m,&n);
    53     for(int i=1;i<=n;i++)
    54     {
    55         scanf("%d%d%d",&price[0][i],&lv[i],&sum[i]);
    56         for(int j=1;j<=sum[i];j++)
    57         {
    58            int t,less;
    59            scanf("%d%d",&t,&less);
    60            price[t][i]=less;
    61         }
    62     }
    63     int minPrice=inf;
    64     int maxLv;
    65     int tempPrice;
    66     for(int i=1;i<=n;i++)
    67     {
    68         maxLv=lv[i];
    69         for(int j=1;j<=n;j++)   //遍历其他各点
    70         {
    71             if(lv[j]>maxLv || maxLv-lv[j]>m)
    72                 bools[j]=true;
    73             else
    74                 bools[j]=false;
    75         }
    76         tempPrice=dijkstra();
    77         if(minPrice>tempPrice)
    78             minPrice=tempPrice;
    79     }
    80     printf("%d
    ",minPrice);
    81     return 0;
    82 }
  • 相关阅读:
    使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果
    Android 实现文件上传功能(upload)
    Hibernate配置文件
    ICMP报文分析
    AVC1与H264的差别
    内存泄漏以及常见的解决方法
    数据挖掘十大经典算法
    关于java的JIT知识
    Ubuntu安装二:在VM中安装Ubuntu
    hdu 1520Anniversary party(简单树形dp)
  • 原文地址:https://www.cnblogs.com/PJQOOO/p/4248252.html
Copyright © 2011-2022 走看看