图论:网络流最大流dinic算法
增添了弧优化,bfs提前判断
点击查看折叠代码块
/*
时间复杂度:
O(N*N*M)
*/
#include <bits/stdc++.h>
#define DEBUG
#define d1(x) std::cout << #x " = " << (x) << std::endl
#define d2(x, y) std::cout << #x " = " << (x) << " ," #y " = " << (y) << std::endl
#define disp(arry, fr, to) \
{ \
std::cout << #arry " : "; \
for(int _i = fr; _i <= to; _i++) std::cout << arry[_i] << " "; \
std::cout << std::endl; \
}
#define ed end()
#define bg begin()
#define mp make_pair
#define pb push_back
#define vv(T) v(v(T))
#define v(T) vector<T>
#define all(x) x.bg,x.ed
#define newline puts("")
#define si(x) ((int)x.size())
#define rep(i,n) for(int i=1;i<=n;++i)
#define rrep(i,n) for(int i=0;i<n;++i)
#define srep(i,s,t) for(int i=s;i<=t;++i)
#define drep(i,s,t) for(int i=t;i>=s;--i)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2e5+10;
const int inf = 0x7f7f7f7f;
const ll inf_ll = 1ll*inf*inf;
const int Mod = 1e9+7;
const double eps = 1e-7;
int head[maxn*2],cnt=0;
struct edge{
int v,next;
ll c;
}e[maxn*10];
void add(int u,int v,ll c){
e[cnt].v=v;e[cnt].c=c;e[cnt].next=head[u];head[u]=cnt++;
e[cnt].v=u;e[cnt].c=0;e[cnt].next=head[v];head[v]=cnt++;
}
int n,m;
int s,t;
int dis[maxn];
int cur[maxn];
bool bfs(int s,int t){
memset(dis,-1,sizeof(dis));
dis[s] = 0;
cur[s]=head[s];
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for (int i=head[u];~i;i=e[i].next){
int v=e[i].v;
ll c=e[i].c;
if(c && dis[v]==-1){
dis[v]=dis[u]+1;
cur[v]=head[v];
q.push(v);
if(v == t) return 1;
}
}
}
return dis[t]!=-1;
}
ll dfs(int u,int t,ll flow){
if(u==t) return flow;
ll delta = flow;
for (int i=cur[u];~i;i=e[i].next){
cur[u] = i;
int v=e[i].v;
ll c=e[i].c;
if(c>0 && dis[v]==dis[u]+1){
ll d=dfs(v,t,min(c,delta));
if(!d) dis[v]=0;
e[i].c-=d;
e[i^1].c+=d;
delta-=d;
if(delta==0) break;
}
}
return flow-delta;
}
ll dinic(int s,int t){
ll ans=0;
while(bfs(s,t)){
//memcpy(cur,head,sizeof(cur));
ans+=dfs(s,t,inf);
}
return ans;
}
int main(){
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d%d%d%d",&n,&m,&s,&t);
rep(i,m){
int u,v;
ll c;
scanf("%d%d%lld",&u,&v,&c);
add(u,v,c);
}
ll ans = dinic(s,t);
printf("%lld\n",ans);
return 0;
}