之前寫Isap的時候,老是被卡,而後學了一發Isap的當前弧優化,好像能夠水過不少題
可是一直沒明白爲啥Isap會走一個環???node
而後寫dinic了,據說不容易被卡(來自去年九省聯考的指導)c++
然而……我寫了一遍上下界最小流,T了。。
後來發現我仍是不懂爲啥要當前弧,由於不會有環
因而去詢問羣友……
說是會重複訪問流滿的邊
那麼爲了防止這一點,記錄一個邊表的指針,流到了立馬返回流量,這樣流第二次過來的時候,就會從最近的一條沒流滿的邊開始流了優化
而後扔個板子。。spa
感受本身水平不行。。。指針
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 //#define ivorysi #define MAXN 50010 #define MAXM 200005 using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 +c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } struct node { int to,next,cap; }E[MAXM * 2]; int N,M,S,T,s,t; int head[MAXN],last[MAXN],sumE = 1,deg[MAXN],Sflow,low[MAXM],cur[MAXN]; int dis[MAXN]; void add(int u,int v,int c) { E[++sumE].to = v; E[sumE].next = head[u]; E[sumE].cap = c; head[u] = sumE; } void addtwo(int u,int v,int c) { add(u,v,c);add(v,u,0); } queue<int> Q; bool BFS() { memset(dis,0,sizeof(dis)); while(!Q.empty()) Q.pop(); Q.push(S);dis[S] = 1; while(!Q.empty()) { int u = Q.front();Q.pop(); for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(E[i].cap > 0) { if(!dis[v]) { dis[v] = dis[u] + 1; if(v == T) return true; Q.push(v); } } } } return dis[T] != 0; } int dfs(int u,int aug) { if(u == T) return aug; for(int &i = cur[u] ; i ; i = E[i].next) { int v = E[i].to; if(E[i].cap > 0) { if(dis[v] == dis[u] + 1) { int t = dfs(v,min(E[i].cap,aug)); if(t) { E[i].cap -= t; E[i ^ 1].cap += t; return t; } } } } return 0; } int Dinic() { int res = 0; while(BFS()) { memcpy(cur,head,sizeof(head)); while(int d = dfs(S,1e9)) { res += d; } } return res; } void Solve() { read(N);read(M);read(s);read(t); S = N + 1;T = S + 1; int a,b,u,l; for(int i = 1 ; i <= M ; ++i) { read(a);read(b);read(l);read(u); addtwo(a,b,u - l); low[i] = l; deg[a] -= l; deg[b] += l; } for(int i = 1 ; i <= N ; ++i) { if(deg[i] > 0) {addtwo(S,i,deg[i]);Sflow += deg[i];} else addtwo(i,T,-deg[i]); } Sflow -= Dinic(); addtwo(t,s,1e9); Sflow -= Dinic(); if(Sflow != 0) puts("please go home to sleep"); else {out(E[sumE].cap);enter;} } int main(){ #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }