• poj 1062 昂贵的聘礼


    题目链接:

      http://poj.org/problem?id=1062

    题目意思:

      中文题目,我就不再废话了。但是有一点要提醒的是在整个交易网中,参加交易的人的最高级别和最低级别差不能超过m,而不是与相邻交易的级别差不超过m,经过一下午的纠结以后,血淋淋的教训告诉我们以后读题目一定要认真,写代码之前要思考,思考时候要慎重。

    解题思路:

      本题最重要的是要想清楚怎么建造图更合适。

      1:我们可以建造一个0点代表虚拟的原点,把1当成终点,以此转化为求到1的最短路。

      2:交换是有方向的,只能单向交换,要建立有向图。

      3:一个合法的交易链中,级别最高级别和最低级别差别不能超过m。

      4:起点不能确定,所以要枚举比较得出最短。

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <iostream>
     7 using namespace std;
     8 #define maxn 110
     9 #define INF 0x3f3f3f3f
    10 
    11 struct node
    12 {
    13     int val[maxn];//可以与之交换的物品的价格
    14     int num[maxn];//可以与之交换的物品的编号
    15     int p, l, x;
    16 }goods[maxn];
    17 
    18 int map[maxn][maxn], n, m;
    19 void init ();
    20 int dijk (int x);//用dijkstra求最短路
    21 
    22 int main ()
    23 {
    24     int i, j;
    25     while (scanf ("%d %d", &m, &n) != EOF)
    26     {
    27         init ();
    28         memset (goods, 0, sizeof(goods));
    29         for (i=1; i<=n; i++)
    30         {
    31             scanf ("%d %d %d", &goods[i].p, &goods[i].l, &goods[i].x);
    32             map[0][i] = goods[i].p;//设定一个虚拟的原点,避免所建图中没有边,无法进行计算
    33             for (j=0; j<goods[i].x; j++)
    34                 scanf ("%d %d", &goods[i].num[j], &goods[i].val[j]);
    35         }
    36         for (i=1; i<=n; i++)
    37             for (j=0; j<goods[i].x; j++)
    38                 if (abs(goods[goods[i].num[j]].l - goods[i].l) <= m && map[goods[i].num[j]][i] > goods[i].val[j])
    39                 {//在合法的等级范围内建边,并且尽量建立最短的边
    40                         map[goods[i].num[j]][i] = goods[i].val[j];
    41                 }
    42 
    43         int mi = INF;
    44         for (i=1; i<=n; i++)//对所有有效的等级进行遍历
    45             mi = min (mi, dijk(i));
    46         printf ("%d
    ", mi);
    47     }
    48     return 0;
    49 }
    50 
    51 void init ()
    52 {
    53     int i, j;
    54     for (i=0; i<=n; i++)
    55         for (j=0; j<=n; j++)
    56             map[i][j] = INF;
    57 }
    58 
    59 int dijk (int x)
    60 {
    61     int dist[maxn], vis[maxn], i, j;
    62     int high = goods[x].l + m;//等级最大值
    63     int low = goods[x].l;//等级最小值
    64     memset (vis, 0, sizeof(vis));
    65     for (i=0; i<=n; i++)//在有效等级内初始化为有效值,否则为INF
    66         if (low <= goods[i].l && goods[i].l <= high)
    67             dist[i] = map[0][i];
    68         else
    69             dist[i] = INF;
    70 
    71     vis[0] = 1;
    72 
    73     for (j=0; j<n; j++)
    74     {
    75         int mi = INF, index;
    76         for (i=0; i<=n; i++)
    77         {//因为无效等级的dist为INF,不需要对点的等级判断
    78             if (!vis[i] && dist[i] < mi)
    79             {
    80                 mi = dist[i];
    81                 index = i;
    82             }
    83         }
    84         if (mi == INF)
    85             break;//图中各点有可能不是联通的,会造成下一步数组越界
    86         vis[index] = 1;
    87 
    88         for (i=0; i<=n; i++)//加入最优点以后,对现有边进行松弛
    89         if (!vis[i] && low<=goods[i].l && goods[i].l <=high && map[index][i] + dist[index] < dist[i])
    90             dist[i] = dist[index] + map[index][i];
    91     }
    92     return dist[1];
    93 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Verilog语言
    OrCAD --从SNAPEDA导入封装库
    RAM/ROM IP一次性总结
    USB之Main item, Local item和Global item 的作用范围与归类
    发光LED压降与工作电流总结
    C之输入输出函数(3) -- 请使用sscanf()
    C之输入输出函数(2) -- gets()
    C之输入输出函数(1) -- fgets()
    C中的lvalue和rvalue
    关于字符串的一点补充
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4229542.html
Copyright © 2020-2023  润新知