POJ 3169 C

题意

  有n头奶牛从1到n编号,按照编号顺序站成一排,有可能有多头奶牛站在同一个坐标上。一些奶牛互相喜欢,所以他们的距离不能大于某个距离,一些奶牛互相讨厌,所以他们的距离不能小于某个距离,请计算如果可能的话1到n的最大距离是多少 

分析

标准的差分约束的裸题。题中的条件可以做如下转化

1.A和B的距离不得超过x:  B-A<=x

2.C和D的距离不得小于y:C-D>=y也就是D-C<=-y

3.奶牛按照编号顺序排序:位置 pos[i+1]-pos[i]>=0也就是pos[i]-pos[i+1]<=0

这样把关系全部变成了小于关系,求最大距离的话建图以后跑一个最短路就行。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <queue>
 6 
 7 using namespace std;
 8 const int maxn=1000+10;
 9 const int maxm=40000+10;
10 const int INF=2147000000;
11 
12 int head[maxn],Next[maxm],to[maxm],val[maxm];
13 int n,ml,md,sz;
14 void add_edge(int a,int b,int w){
15     ++sz;
16     to[sz]=b;
17     val[sz]=w;
18     Next[sz]=head[a];
19     head[a]=sz;
20 }
21 int a,b,w;
22 int spfa(){
23     int d[maxn],vis[maxn],cnt[maxn];
24     memset(vis,0,sizeof(d));
25     memset(cnt,0,sizeof(cnt));
26     for(int i=0;i<=n;i++)d[i]=INF;
27     queue<int>q;
28     q.push(n);
29     d[n]=0;vis[n]=1;cnt[n]=1;
30     while(!q.empty()){
31         int u=q.front();q.pop();vis[u]=0;
32     //    cout<<u<<endl;
33         for(int i=head[u];i;i=Next[i]){
34             int v=to[i];
35             if(d[v]>d[u]+val[i]){
36                 d[v]=d[u]+val[i];
37                 if(!vis[v]){
38                     vis[v]=1;
39                     q.push(v);
40                     cnt[v]++;
41                     if(cnt[v]>n){
42                         return -1;
43                     }
44                 }
45             }
46         }
47     }
48     if(d[1]==INF)
49         return -2;
50     return d[1];
51 }
52 int main(){
53     scanf("%d%d%d",&n,&ml,&md);
54     for(int i=1;i<=ml;i++){
55         scanf("%d%d%d",&a,&b,&w);
56         add_edge(b,a,w);
57     }
58     for(int i=1;i<=md;i++){
59         scanf("%d%d%d",&a,&b,&w);
60         add_edge(a,b,-w);
61     }
62     for(int i=1;i<n;i++){
63         add_edge(i,i+1,0);
64     }
65     int ans=spfa();
66     printf("%d",ans);
67 
68 return 0;
69 }
View Code
原文地址:https://www.cnblogs.com/LQLlulu/p/8893099.html