loj #116. 有源汇有上下界最大流

题目链接

 

有源汇有上下界最大流,->上下界网络流

注意细节,重置cur和dis数组时,有n+2个点

 

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<iostream>
  6 
  7 using namespace std;
  8 
  9 const int N = 10010;
 10 const int INF = 1e9;
 11 
 12 struct Edge {
 13     int to,nxt,c;
 14 }e[100100];
 15 int head[N],dis[N],cur[N],M[N];
 16 int q[100100],L,R;
 17 int n,m,S,T,tot = 1,Sum;
 18 
 19 inline char nc() {
 20     static char buf[100000],*p1 = buf,*p2 = buf;
 21     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
 22 }
 23 inline int read() {
 24     int x = 0,f = 1;char ch = nc();
 25     for (; ch<'0'||ch>'9'; ch=nc()) if(ch=='-') f=-1;
 26     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
 27     return x * f;
 28 }
 29 void add_edge(int u,int v,int c) {
 30     e[++tot].to = v,e[tot].c = c,e[tot].nxt = head[u],head[u] = tot;
 31 }
 32 bool bfs() {
 33     for (int i=1; i<=n+2; ++i) // n+2
 34         cur[i] = head[i],dis[i] = -1;
 35     L = 1,R = 0;
 36     q[++R] = S;
 37     dis[S] = 0;
 38     while (L <= R) {
 39         int u = q[L++];
 40         for (int i=head[u]; i; i=e[i].nxt) {
 41             int v = e[i].to;
 42             if (dis[v] == -1 && e[i].c > 0) {
 43                 dis[v] = dis[u] + 1;
 44                 q[++R] = v;
 45                 if (v == T) return true;
 46             }
 47         }
 48     }
 49     return false;
 50 }
 51 int dfs(int u,int flow) {
 52     if (u == T) return flow;
 53     int used = 0;
 54     for (int &i=cur[u]; i; i=e[i].nxt) {
 55         int v = e[i].to;
 56         if (dis[v] == dis[u] + 1 && e[i].c > 0) {
 57             int tmp = dfs(v,min(e[i].c,flow-used));
 58             if (tmp > 0) {
 59                 e[i].c -= tmp;e[i^1].c += tmp;
 60                 used += tmp;
 61                 if (used == flow) break;
 62             }
 63         }
 64     }
 65     if (used != flow) dis[u] = -1;
 66     return used;
 67 }
 68 int dinic(int s,int t) {
 69     S = s,T = t;
 70     int ans = 0;
 71     while (bfs()) ans += dfs(S,INF);
 72     return ans;
 73 }
 74 int main () {
 75     freopen("1.txt","r",stdin);
 76     n = read(),m = read();
 77     int s = read(),t = read();
 78     int ss = n+1,tt = n+2;
 79     for (int i=1; i<=m; ++i) {
 80         int u = read(),v = read(),b = read(),c = read();
 81         add_edge(u,v,c-b);
 82         add_edge(v,u,0);
 83         M[u] -= b;M[v] += b;
 84     }
 85     for (int i=1; i<=n; ++i) {
 86         if (M[i] > 0) add_edge(ss,i,M[i]),add_edge(i,ss,0),Sum += M[i];
 87         if (M[i] < 0) add_edge(i,tt,-M[i]),add_edge(tt,i,0);
 88     }
 89     add_edge(t,s,INF);
 90     add_edge(s,t,0);
 91     if (dinic(ss,tt) != Sum) {
 92         puts("please go home to sleep");
 93         return 0;
 94     }
 95     int ans = e[tot].c;
 96     e[tot].c = 0;e[tot ^ 1].c = 0;
 97     ans += dinic(s,t);
 98     printf("%d\n",ans);
 99     return 0;
100 }

 

posted @ 2018-02-25 10:50  MJT12044  阅读(381)  评论(0编辑  收藏  举报