昨天学习了网络流,可算弄明白了。把学习过程中看的博客和视频贴一下,大佬们讲的很好了,我就不写了赖得写了
先看基本概念:博客链接这篇文章讲的很好,也讲了许多求最大流的算法,其中最好理解的是EK算法,但是效率不高,Dicnic算法是其改进版,也是竞赛经常用到的算法
如果看完文章之后EK和Dicnic算法没看懂的话,我再贴两个讲解这两个算法的视频
看完这些博客和视频我想你已经弄懂了
写一个板子题练一下板子题HDU Drainage Ditches
EK算法题解:复杂度o(VE^2)
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
typedef pair<ll,ll> pa;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll maxn=220;
ll N,M,G[maxn][maxn],pre[maxn],flow[maxn];
queue<ll>Q;
ll BFS(ll S,ll T){
while(!Q.empty())
Q.pop();
memset(pre,-1,sizeof(pre));
flow[S]=INF;
Q.push(S);
while(!Q.empty()){
ll u=Q.front();
Q.pop();
if(u==T)
break;
for(ll v=1;v<=N;v++){
if(v!=S&&G[u][v]>0&&pre[v]==-1){
flow[v]=min(flow[u],G[u][v]);
pre[v]=u;
Q.push(v);
}
}
}
if(pre[T]==-1)
return -1;
return flow[T];
}
ll EK(ll S,ll T){
ll delta,maxflow=0;
while(1){
delta=0;
delta=BFS(S,T);
if(delta==-1)
break;
ll p=T;
while(p!=S){
G[pre[p]][p]-=delta;
G[p][pre[p]]+=delta;
p=pre[p];
}
maxflow+=delta;
}
return maxflow;
}
int main()
{
while(~scanf("%lld %lld",&M,&N)){
ll i,j,u,v,w;
memset(G,0,sizeof(G));
memset(flow,0,sizeof(flow));
for(i=1;i<=M;i++){
scanf("%lld %lld %lld",&u,&v,&w);
G[u][v]+=w;
}
printf("%lld\n",EK(1,N));
}
return 0;
}
Dicnic算法题解:在普通情况下, DINIC算法时间复杂度为O(V2E) 在二分图中, DINIC算法时间复杂度为O(√VE)
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
typedef pair<ll,ll> pa;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll maxn=220;
const ll maxm=220;
ll dep[maxn],head[maxn],cnt=0,N,M,S,T,cur[maxn];
struct node{
ll v,w,next;
}edge[maxm<<1];
void add(ll u,ll v,ll w){
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
return ;
}
bool BFS(ll S,ll T){
ll i,j;
for(i=1;i<=N;i++)
dep[i]=-1;
dep[S]=0;
queue<ll>Q;
Q.push(S);
while(!Q.empty()){
ll u=Q.front();
Q.pop();
for(i=head[u];~i;i=edge[i].next){
ll v=edge[i].v,w=edge[i].w;
if(w&&dep[v]==-1){
dep[v]=dep[u]+1;
Q.push(v);
}
}
}
return dep[T]!=-1;
}
ll DFS(ll now,ll fl){
ll i,j;
if(now==T)
return fl;
ll f=0;
for(i=cur[now];~i;i=edge[i].next){
cur[now]=edge[i].next;
ll v=edge[i].v,w=edge[i].w;
if(dep[v]==dep[now]+1&&w){
ll x=DFS(v,min(w,fl));
if(x<=0)
continue;
edge[i].w-=x;
edge[i^1].w+=x;
fl-=x;
f+=x;
if(fl<=0)
break;
}
}
if(!f)
dep[now]=-1;
return f;
}
ll Dinic(ll S,ll T){
ll res=0;
while(BFS(S,T)){
for(ll i=1;i<=N;i++)
cur[i]=head[i];
res+=DFS(S,INF);
}
return res;
}
int main()
{
while(~scanf("%lld %lld",&M,&N)){
memset(head,-1,sizeof(head));
cnt=0;
ll i,j,u,v,w;
for(i=0;i<M;i++){
scanf("%lld %lld %lld",&u,&v,&w);
add(u,v,w);
add(v,u,0);
}
S=1,T=N;
printf("%lld\n",Dinic(S,T));
}
return 0;
}