POJ - 3169 Layout (差分约束)

Layout  

差分约束:

形如:$x1-x2>=a,x1-x3>=b,x2-x3<=c$

出现这样式子便要用到差分约束加最短路了。当要求$x1与x3$的最大差值时要用到最短路,所有的式子要转换成$x1-x2<=a$的形式,当求最小值时用最长路,所有式子转换为$x1-x2>=a$的形式。至于建图则需要根据题意确定边的方向。

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

题目大意:

n头牛,从1到n排序,每头牛按照序号在一条直线排队,允许一个位置有多头牛,有些牛有喜欢的或不喜欢的牛,所以对彼此之间的距离有要求,要求出第1头牛与第n头牛之间的最大距离。

解题思路:

求最大距离,用最短路,存在负值,也就有可能有负环,用spfa。因为要判断能不能排队,所以要建一个超级源点,连接所有的牛,并经过所有的边。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <vector>
 5 #include <queue>
 6 using namespace std;
 7 typedef long long ll;
 8 #define debug(a) cout<<#a<<":"<<a<<endl;
 9 const int INF=0x3f3f3f3f;
10 const int N=1e6+7;
11 const int mod=1e9+7;
12 int maxn,minn;
13 int T,n;
14 int u,v,w;
15 int dis[N];
16 int vis[N];
17 int cnt[N];
18 struct aa{
19     int u,w;
20 }p;
21 vector<aa>mp[N];
22 bool spfa(int a){
23     memset(vis,0,sizeof(vis));
24     memset(dis,INF,sizeof(dis));
25     memset(cnt,0,sizeof(cnt));
26     queue<int>que;
27     que.push(a);
28     dis[a]=0;
29     while(!que.empty()){
30         int a=que.front();
31         vis[a]=0;
32         que.pop();
33         for(int i=0;i<mp[a].size();i++){
34             p=mp[a][i];
35             if(dis[p.u]>dis[a]+p.w){
36                 dis[p.u]=dis[a]+p.w;
37                 cnt[p.u]=cnt[a]+1;
38                 if(cnt[p.u]>=n){
39                     return true;
40                 }
41                 if(vis[p.u]==0){
42                     que.push(p.u);
43                     vis[p.u]=1;
44                 }
45             }
46         }
47     }
48     return false;
49 }
50 int main(){
51     int m1,m2;
52     cin>>n>>m1>>m2;
53     for(int i=1;i<=m1;i++){
54         cin>>u>>v>>w;
55         p.u=v;
56         p.w=w;
57         mp[u].push_back(p);
58     }
59     for(int i=1;i<=m2;i++){
60         cin>>u>>v>>w;
61         p.w=-w;
62         p.u=u;
63         mp[v].push_back(p);
64     }
65     for(int i=1;i<n;i++){
66         p.u=i;
67         p.w=0;
68         mp[i+1].push_back(p);
69     } 
70     if(spfa(n)){
71         puts("-1");
72     }
73     else{
74         spfa(1);
75         if(dis[n]>=INF/2){
76             puts("-2");
77         }
78         else{
79             printf("%d\n",dis[n]);
80         }
81     }
82     return 0;
83 }

 

posted @ 2020-04-23 15:50  yya雨  阅读(158)  评论(0编辑  收藏  举报