模板 有源汇上下界最小流 loj117

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 using namespace std;
  5 typedef long long ll;
  6 const int maxn = 51000,maxm = 800000;
  7 ll inf = 1e16;
  8 int cnt = 1,ss,tt,s,t,n,m;
  9 int head[maxn],iter[maxn],dis[maxn],nxt[maxm],to[maxm];
 10 ll flow[maxm],d[maxn],low[maxm];
 11 bool inq[maxn]; 
 12 void add(int a,int b,ll fl)
 13 {
 14     nxt[++cnt] = head[a];
 15     to[cnt] = b;
 16     head[a] = cnt;
 17     flow[cnt] = fl;
 18     nxt[++cnt] = head[b];
 19     to[cnt] = a;
 20     head[b] = cnt;
 21     flow[cnt] = 0;
 22 }
 23   
 24 bool bfs()
 25 {
 26     queue <int> que;
 27     memset(inq,0,sizeof(inq));
 28     que.push(tt);
 29     inq[tt] = 1;
 30     dis[tt] = 0;
 31     while (!que.empty())
 32     {
 33         int cur = que.front();
 34         que.pop();
 35         for (int i = head[cur];i;i = nxt[i])
 36         {
 37             int v = to[i];
 38             if (!inq[v] && flow[i ^ 1])
 39             {
 40                 dis[v] = dis[cur] + 1;
 41                 que.push(v);
 42                 inq[v] = 1;
 43             }
 44         }
 45     }
 46     return inq[ss];
 47 }
 48 ll dfs(int u, ll delta)
 49 {
 50     if(u == tt) return delta;
 51     ll ret = 0;
 52     for (int &i = iter[u];i;i = nxt[i]) if(dis[to[i]] + 1 == dis[u] && flow[i])
 53     {
 54         ll x = dfs(to[i], min(delta,flow[i]));
 55         ret += x;
 56         delta -= x;
 57         flow[i] -= x;
 58         flow[i ^ 1] += x; 
 59         if (delta == 0)
 60             break;   
 61     }
 62     return ret;
 63 }
 64 ll maxflow() 
 65 {
 66     ll ret = 0;
 67     while (bfs())
 68     {
 69         for (int i = 1;i <= n + 2;i++)
 70             iter[i] = head[i];
 71         ll fl = 0;
 72         do
 73         {
 74                ll fl = dfs(ss,inf);
 75             ret += fl;
 76           } while (fl);
 77     }
 78     return ret;
 79 }
 80 
 81 //cnt = 1
 82 int main()
 83 {
 84     scanf("%d%d%d%d",&n,&m,&s,&t);
 85     ss = n + 1;
 86     tt = n + 2;
 87     int tx,ty;
 88     ll tl,tu;
 89     for (int i = 1;i <= m;i++)
 90     {
 91         scanf("%d%d%lld%lld",&tx,&ty,&tl,&tu);
 92         add(tx,ty,tu - tl);
 93         d[tx] -= tl;
 94         d[ty] += tl;
 95         low[i] = tl;
 96     }
 97     ll sum = 0;
 98     for (int i = 1;i <= n;i++)
 99         if (d[i] > 0)
100         {
101             sum += d[i];
102             add(ss,i,d[i]);
103         }else if (d[i] < 0)
104             add(i,tt,-d[i]); 
105     ll flow1 = maxflow();
106     add(t,s,inf);
107     ll flow2 = maxflow();
108     if (flow1 + flow2 < sum)
109     {
110         printf("please go home to sleep");
111         return 0;
112     }
113     printf("%lld\n",flow[cnt]);
114     return 0;
115 }

 

posted @ 2019-11-14 21:20  IAT14  阅读(159)  评论(0编辑  收藏  举报