- 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
题目分析:
-
b
f
s
bfs
bfs判断能否继续增广
-
d
f
s
dfs
dfs实现增广
- 重复此过程
Code:
#include <bits/stdc++.h>
using namespace std;
#define maxn 10010
#define maxm 100010
#define INF 1000000007
int n,m,s,t,size=1,head[maxn],d[maxn],cur[maxn];
struct edge {
int v,w,nxt;
}e[maxm<<1];
inline void init_() {
freopen("a.txt","r",stdin);
}
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x*f;
}
inline void add_(int u,int v,int w) {
e[++size].v=v;
e[size].w=w;
e[size].nxt=head[u];
head[u]=size;
}
inline void clean_() {
memset(head,-1,sizeof(head));
}
inline int bfs_() {
memset(d,-1,sizeof(d));
d[t]=0;
queue<int >q;
q.push(t);
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(d[v]==-1&&e[i^1].w>0) {
d[v]=d[u]+1;
q.push(v);
}
}
}
return ~d[s];
}
int dfs_(int u,int flow) {
if(u==t||!flow) return flow;
int data=flow;
for(int &i=cur[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(d[u]==d[v]+1&&e[i].w>0) {
int dis=dfs_(v,min(data,e[i].w));
e[i].w-=dis;
e[i^1].w+=dis;
data-=dis;
if(!data) break;
}
}
return flow-data;
}
int dinic_() {
int ans=0;
while(bfs_()) {
for(int i=1;i<=n;++i) {
cur[i]=head[i];
}
ans+=dfs_(s,INF);
}
return ans;
}
void readda_() {
n=read_();m=read_();s=read_();t=read_();
clean_();
int x,y,z;
for(int i=1;i<=m;++i) {
x=read_();y=read_();z=read_();
add_(x,y,z);add_(y,x,0);
}
printf("%d",dinic_());
}
int main() {
init_();
readda_();
return 0;
}