poj3169Layout(差分约束)

来源:互联网 发布:淘宝零食大礼包划算吗 编辑:程序博客网 时间:2024/04/30 01:24

题意

有n头牛,编号是1~n,他们按编号顺序排成一排,这些牛之间有关系好的和关系坏的,关系好的ml对牛,给出他们之间的距离的最大值,关系差的md对牛,给出他们之间距离的最小值。牛可以站在同一个位置上。在满足这些条件的情况下,求编号为1的牛和n的牛距离的最大值。

思路

假如第i头牛的位置为dist[i],那么必定有dist[i] <= dist[i + 1],然后有最大距离限制,dist[a[i]] + dl[i] <= dist[b[i]],最小距离限制dist[a[i]] + dd[i] >= dist[b[i]],这些关系都可以转化成a - b <= c的形式,我们建一条b->a的权值为c的边,形成的这个图,求最短路即是最长距离,(证明:a - b <= x1, b - c <= x2, a - c <= x3, a - c <= min(x1 + x2, x3))。

代码

#include <cstdio>#include <iostream>using namespace std;const int kMaxn = 10000 + 10;const int kInf = 0x3f3f3f3f;struct Edge {  int u,v;  int w;} g[kMaxn * 3];int dist[kMaxn];int n,ml,md,top;void Init() {  top = 0;}void AddEdge(int a, int b, int d) {  top++;  g[top].u = a;  g[top].v = b;  g[top].w = d;}void Bellman_Ford(int s, int t) {  for(int i = 1; i <= n; i++)    dist[i] = kInf;  dist[s] = 0;  for(int k = 1; k < n; k++) {    for(int i = 1; i <= top; i++) {      if(dist[g[i].u] != kInf && dist[g[i].u] + g[i].w < dist[g[i].v])    dist[g[i].v] = dist[g[i].u] + g[i].w;    }  }}int main() {  while(~scanf("%d %d %d", &n, &ml, &md)) {    int a,b,d;    Init();    for(int i = 1; i <= ml; i++) {      scanf("%d %d %d", &a, &b, &d);      AddEdge(a, b, d);    }    for(int i = 1; i <= md; i++) {      scanf("%d %d %d", &a, &b, &d);      AddEdge(b, a, -d);    }    //printf("%d\n", top);    for(int i = 1; i < n; i++)      AddEdge(i + 1, i, 0);    //printf("%d\n", top);    Bellman_Ford(1, n);    if(dist[1] < 0)      printf("-1\n");    else if(dist[n] == kInf)      printf("-2\n");    else       printf("%d\n", dist[n]);  }  return 0;}
0 0
原创粉丝点击