模板 有源汇上下界最小流 loj117
Posted iat14
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 有源汇上下界最小流 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 ",flow[cnt]); 114 return 0; 115 }
以上是关于模板 有源汇上下界最小流 loj117的主要内容,如果未能解决你的问题,请参考以下文章