差分约束 刷题记录

Posted jiecaoer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了差分约束 刷题记录相关的知识,希望对你有一定的参考价值。

把问题转化成一堆不等式,然后用最短路求解

POJ3169 Layout

最后要求1和n之间最大dis是多少  ->  转化为得到一堆  d[n] - d[1] <= xi  然后求xi的最小值

对于给出的是d[u] - d[v] >= xi  同乘-1转化为 d[v] - d[u] <= -xi 即可

然后用spfa求 1到n的最短路

若有负环则无解,若求得的最短路为inf则说明1,n间距离可随便大

代码:

技术图片
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <queue>
 4 #define nmax 50010
 5 #define f(c,a,b) for(int c=a; c<=b; c++)
 6 
 7 using namespace std;
 8 typedef long long ll;
 9 struct edge{
10     int v, ne, w;
11 }e[nmax];
12 int cnt=0, n, x, y;
13 int head[nmax]={0}, c[nmax]={0}, inq[nmax]={0};
14 ll d[nmax]={0};
15 const ll inf = 1e15;
16 
17 void addedge(int u, int v, int w){
18     cnt++;
19     e[cnt].v = v;
20     e[cnt].w = w;
21     e[cnt].ne = head[u];
22     head[u] = cnt;
23 }
24 
25 void build(){
26     scanf("%d%d%d", &n, &x, &y);
27     int u, v, w;
28     f(i, 1, x){
29         scanf("%d%d%d", &u, &v, &w);
30         addedge(u, v, w);
31     }
32     f(i, 1, y){
33         scanf("%d%d%d", &u, &v, &w);
34         addedge(v, u, -w);
35     }
36     f(i, 2, n) d[i] = inf;
37 }
38 
39 bool spfa(){
40     queue <int> q;
41     q.push(1);
42     inq[1] = c[1] = 1;
43     while(!q.empty()){
44         int u = q.front();
45         if( c[u] > n ) return false;
46         q.pop();
47         inq[u] = 0;
48         for (int i=head[u]; i; i=e[i].ne){
49             int v = e[i].v;
50             if(d[v] > d[u] + e[i].w){
51                 d[v] = d[u] + e[i].w;
52                 if(inq[v]) continue;
53                 inq[v] = 1;
54                 c[v]++;
55                 q.push(v);
56             }
57         }
58     }
59     return true;
60 }
61 
62 int main(){
63     build();
64     if( spfa() ){
65         if(d[n]==inf) printf("-2
");
66         else printf("%lld
", d[n]);
67     }else{
68         printf("-1
");
69     }
70     return 0;
71 }
??

 

以上是关于差分约束 刷题记录的主要内容,如果未能解决你的问题,请参考以下文章

2019.8.3刷题统计

差分约束系统

浅谈差分约束系统

noip刷题记录 20170818

差分约束

题解ZOJ1420 Cashier Employment