图论:有源汇有上下界最大流

可行流会求了,这次求最大流

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int inf = 0x3f3f3f3f;
  4 const int maxn = 210;
  5 const int maxm = 50010;
  6 struct G
  7 {
  8     int v, cap, next, num;
  9     G() {}
 10     G(int v, int cap, int next, int num) : v(v), cap(cap), next(next), num(num) {}
 11 } E[maxm];
 12 int p[maxn], T;
 13 int d[maxn], temp_p[maxn], qw[maxn]; //d顶点到源点的距离标号,temp_p当前狐优化,qw队列
 14 int n,m,s,t;
 15 void init()
 16 {
 17     memset(p, -1, sizeof(p));
 18     T = 0;
 19 }
 20 void add(int u, int v, int cap, int num)
 21 {
 22     E[T] = G(v, cap, p[u], num);
 23     p[u] = T++;
 24     E[T] = G(u, 0, p[v], num);
 25     p[v] = T++;
 26 }
 27 bool bfs(int st, int en, int n)
 28 {
 29     int i, u, v, head, tail;
 30     for(i = 0; i <= n; i++) d[i] = -1;
 31     head = tail = 0;
 32     d[st] = 0;
 33     qw[tail] = st;
 34     while(head <= tail)
 35     {
 36         u = qw[head++];
 37         for(i = p[u]; i + 1; i = E[i].next)
 38         {
 39             v = E[i].v;
 40             if(d[v] == -1 && E[i].cap > 0)
 41             {
 42                 d[v] = d[u] + 1;
 43                 qw[++tail] = v;
 44             }
 45         }
 46     }
 47     return (d[en] != -1);
 48 }
 49 int dfs(int u, int en, int f)
 50 {
 51     if(u == en || f == 0) return f;
 52     int flow = 0, temp;
 53     for(; temp_p[u] + 1; temp_p[u] = E[temp_p[u]].next)
 54     {
 55         G& e = E[temp_p[u]];
 56         if(d[u] + 1 == d[e.v])
 57         {
 58             temp = dfs(e.v, en, min(f, e.cap));
 59             if(temp > 0)
 60             {
 61                 e.cap -= temp;
 62                 E[temp_p[u] ^ 1].cap += temp;
 63                 flow += temp;
 64                 f -= temp;
 65                 if(f == 0)  break;
 66             }
 67         }
 68     }
 69     return flow;
 70 }
 71 int dinic(int st, int en, int n)
 72 {
 73     int i, ans = 0;
 74     while(bfs(st, en, n))
 75     {
 76         for(i = 0; i <= n; i++) temp_p[i] = p[i];
 77         ans += dfs(st, en, inf);
 78     }
 79     return ans;
 80 }
 81 int du[maxn],sum=0;
 82 int main()
 83 {
 84     scanf("%d%d%d%d",&n,&m,&s,&t);
 85     init();
 86     memset(du,0,sizeof(du));
 87     for(int i=1; i<=m; i++){
 88         int u,v,l,r;
 89         scanf("%d %d %d %d", &u,&v,&l,&r);
 90         add(u,v,r-l, i);
 91         du[u]-=l;
 92         du[v]+=l;
 93     }
 94     int ss = 0, tt = n+1;
 95     for(int i=1; i<=n; i++){
 96         if(du[i]>0) sum+=du[i],add(ss,i,du[i], 0);
 97         if(du[i]<0) add(i,tt,-du[i], 0);
 98     }
 99     add(t, s, inf, 0);
100     if(sum == dinic(ss,tt,n+2)){
101         sum = E[p[t]^1].cap;
102         for(int i=0; i<T; i++){
103             if(!E[i].num) E[i].v=0;
104         }
105         p[ss]=p[tt]=-1;
106         ss=s;
107         tt=t;
108         printf("%d\n", sum+dinic(ss,tt,n+2));
109     }
110     else{
111         puts("please go home to sleep");
112     }
113     return 0;
114 }

 

posted @ 2018-09-10 23:00  静听风吟。  阅读(263)  评论(0编辑  收藏  举报