poj 3169 layout

POJ . 3169 Layout

链接:http://poj.org/problem?id=3169

题意 : 

       有N头奶牛排队喂食,它们之间有相互喜欢的,所以这两头相互喜欢的奶牛之间的距离要小于等于ML,同时,有相互讨厌的的奶牛,它们之间的距离要大于等于MD,而且奶牛的位置和他们的标号顺序相同,求奶牛1到奶牛N的最大距离,如果没有最大距离输出-1,最大距离无限大则-2;

       这道题的思路是利用差分约束系统来建图 :

       如果u,v的最大距离为val :( 1 )  dis[ v ] - dis[ u ] < = val;

       如果u,v的最小距离为val: ( 2 )  dis[ u ] - dis[ v ] < = - val;

       又由于它们站位顺序要与编号顺序相同,所以说还需满足:( 3 ) dis[ i ] - dis[ i - 1 ] > = 0;

       由此我们就可以建图了;

代码:

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

const int N = 2 * (1e6 + 1);
queue< int > q;
int tov[N],next[N],head[N],w[N],cnt[1001],dis[N],tot,n,p,m;
bool vis[1001];

void add(int u,int v,int val){
  tot++;
  tov[tot] = v;
  next[tot] = head[u];
  w[tot] = val;
  head[u] = tot;
}

int spfa(){
  vis[1] = true;
  dis[1] = 0;
  q.push(1);
  cnt[1]++;
  while (!q.empty()){
      int u = q.front();
      q.pop();
      for (int i = head[u];i;i = next[i]){
        int v = tov[i];
        if (dis[v] > dis[u] + w[i]){
            dis[v] = dis[u] + w[i];
            if (!vis[v]){
              if ((++cnt[v]) > n) return -1;
              vis[v] = true;
              q.push(v);
            }
        }
      }
      vis[u] = false;
  }
  if (dis[n] == 1e9 + 7) return -2;
  return dis[n];
}

int main(){
  scanf("%d%d%d",&n,&p,&m);
  for (int i = 1;i <= n;i++) dis[i] = 1e9 + 7,add(i,i - 1,0);  //满足不等式3
  for (int i = 1;i <= p;i++){
      int u,v,d;
      scanf("%d%d%d",&u,&v,&d);
      add(u,v,d); //满足不等式1
  }
  for (int i = 1;i <= m;i++){
      int u,v,d;
      scanf("%d%d%d",&u,&v,&d);
      add(v,u,-d);  //满足不等式2
  }
  printf("%d",spfa());
  return 0;
}

 

 

原文地址:https://www.cnblogs.com/ganster/p/8467465.html