zoukankan      html  css  js  c++  java
  • poj 3169 Layout

    题意:

    有一排按顺序排列的牛,i在i+1的前面。

    牛之间存在2种关系:(i < j)

    (i,j,a):i希望离j的距离不超过a;

    (i,j,b):i希望离j的距离不小于b;

    有可能许多牛是在同一个位置。

    给出一些关系,求第一头牛和最后一头牛的距离的最大值。

    思路:

    通过两个关系可以得出两个不等式

    1:d[i] + a >= d[j]

    2:d[i] + a <= d[j]

    有若干个形如上式的不等式,称为差分约束系统,采用最短路的方式求解。

    首先把不等式转化为统一的大于等于的形式(大于等于对应于最短路,小于等于对应于最长路)。

    之后,对应于统一的d[i] + a >= d[j]的形式,则添加一条从i到j的权值为a的边;

    题中还有隐藏关系d[i] <= d[i+1] + 0,则添加一条从i+1到i的权值为0的边。

    因为有负权边,所以用bellman-ford算法。

    当第n次还有边更新的时候,说明有负权回路,无解。其他情况有解。

    坑:

    poj 强行  while (scanf())。。。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 struct edge{int from,to,cost; };
     8 
     9 edge es[30005];
    10 
    11 int dis[1005];
    12 
    13 const int inf = 0x3f3f3f3f;
    14 
    15 bool spfa(int n,int en)
    16 {
    17     memset(dis,inf,sizeof(dis));
    18 
    19     dis[1] = 0;
    20 
    21     for (int i = 1;i <= n;i++)
    22     {
    23         for (int j = 0;j < en;j++)
    24         {
    25             edge e = es[j];
    26 
    27             if (dis[e.to] > dis[e.from] + e.cost)
    28             {
    29                 dis[e.to] = dis[e.from] + e.cost;
    30 
    31                 if (i == n) return true;
    32             }
    33         }
    34     }
    35 
    36     return false;
    37 }
    38 
    39 int main()
    40 {
    41     int n,ml,md;
    42 
    43     while (scanf("%d%d%d",&n,&ml,&md) != EOF)
    44     {
    45         int cnt = 0;
    46 
    47         for (int i = 1;i < n;i++)
    48         {
    49             es[cnt].from = i + 1;
    50             es[cnt].to = i;
    51             es[cnt].cost = 0;
    52             cnt++;
    53         }
    54 
    55         for (int i = 0;i < ml;i++)
    56         {
    57             int a,b,d;
    58 
    59             scanf("%d%d%d",&a,&b,&d);
    60 
    61             es[cnt].from = a;
    62             es[cnt].to = b;
    63             es[cnt].cost = d;
    64 
    65             cnt++;
    66         }
    67 
    68         for (int i = 0;i < md;i++)
    69         {
    70             int a,b,d;
    71 
    72             scanf("%d%d%d",&a,&b,&d);
    73 
    74             es[cnt].from = b;
    75             es[cnt].to = a;
    76             es[cnt].cost = -d;
    77 
    78             cnt++;
    79         }
    80 
    81         bool f = spfa(n,cnt);
    82 
    83         if (f) printf("-1
    ");
    84         else if (dis[n] == inf) printf("-2
    ");
    85         else printf("%d
    ",dis[n]);
    86     }
    87 
    88     return 0;
    89 }
  • 相关阅读:
    点集拓扑的重要内容回顾
    Python(二):多进程与多线程
    动态规划(一):笨办法理解动态规划
    PyPI(一):pipreqs获取当前项目依赖包
    Effective python(五):内置模块
    Python(一):装饰器
    基础数学(十一):速算
    Effective python(四):元类及属性
    基础数学(十):计算与公式
    Effective python(三):类与继承
  • 原文地址:https://www.cnblogs.com/kickit/p/8034905.html
Copyright © 2011-2022 走看看