转载:https://blog.csdn.net/qq_41357771/article/details/79416899
https://blog.csdn.net/cai13160674275/article/details/50834431
EK
#include<iostream>
#include<queue>
using namespace std;
const int maxn=205;
const int inf=0x7fffffff;
int r[maxn][maxn]; //残留网络,初始化为原图
bool visit[maxn];
int pre[maxn];
int m,n;
bool bfs(int s,int t) //寻找一条从s到t的增广路,若找到返回true
{
int p;
queue<int > q;
memset(pre,-1,sizeof(pre));
memset(visit,false,sizeof(visit));
pre[s]=s;
visit[s]=true;
q.push(s);
while(!q.empty())
{
p=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
if(r[p][i]>0&&!visit[i])
{
pre[i]=p;
visit[i]=true;
if(i==t) return true;
q.push(i);
}
}
}
return false;
}
int EdmondsKarp(int s,int t)
{
int flow=0,d,i;
while(bfs(s,t))
{
d=inf;
for(i=t;i!=s;i=pre[i])
d=d<r[pre[i]][i]? d:r[pre[i]][i];
for(i=t;i!=s;i=pre[i])
{
r[pre[i]][i]-=d;
r[i][pre[i]]+=d;
}
flow+=d;
}
return flow;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int u,v,w;
memset(r,0,sizeof(r));///
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
r[u][v]+=w;
}
printf("%d\n",EdmondsKarp(1,n));
}
return 0;
}
EK
#include<iostream>
#include<queue>
using namespace std;
const int maxn=205;
const int inf=0x7fffffff;
int r[maxn][maxn]; //残留网络,初始化为原图
bool visit[maxn];
int pre[maxn];
int m,n;
bool bfs(int s,int t) //寻找一条从s到t的增广路,若找到返回true
{
int p;
queue<int > q;
memset(pre,-1,sizeof(pre));
memset(visit,false,sizeof(visit));
pre[s]=s;
visit[s]=true;
q.push(s);
while(!q.empty())
{
p=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
if(r[p][i]>0&&!visit[i])
{
pre[i]=p;
visit[i]=true;
if(i==t) return true;
q.push(i);
}
}
}
return false;
}
int EdmondsKarp(int s,int t)
{
int flow=0,d,i;
while(bfs(s,t))
{
d=inf;
for(i=t;i!=s;i=pre[i])
d=d<r[pre[i]][i]? d:r[pre[i]][i];
for(i=t;i!=s;i=pre[i])
{
r[pre[i]][i]-=d;
r[i][pre[i]]+=d;
}
flow+=d;
}
return flow;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int u,v,w;
memset(r,0,sizeof(r));///
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
r[u][v]+=w;
}
printf("%d\n",EdmondsKarp(1,n));
}
return 0;
}
Dinic
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 10005
#define MAXE 200005
using namespace std;
int n,m,S,T,hd,tl,que[MAXN],dep[MAXN];
int tot=-1,lnk[MAXN],nxt[MAXE],son[MAXE],C[MAXE],F[MAXE];
int read()
{
int ret=0;
char ch=getchar();
bool f=1;
for(; !isdigit(ch); ch=getchar())
f^=!(ch^'-');
for(; isdigit(ch); ch=getchar())
ret=(ret<<3)+(ret<<1)+ch-48;
return f?ret:-ret;
}
void add(int x,int y,int c,int f)
{
son[++tot]=y;
nxt[tot]=lnk[x];
lnk[x]=tot;
C[tot]=c;
F[tot]=f;
}
bool BFS()
{
hd=0;
que[tl=1]=S;
memset(dep,0,sizeof(dep));
dep[S]=1;//更新点深度,可以说是刷层次
while(hd!=tl)
{
int x=que[++hd];
for(int j=lnk[x]; j!=-1; j=nxt[j])
if(!dep[son[j]]&&C[j]>F[j])
dep[son[j]]=dep[x]+1,que[++tl]=son[j];
}
return dep[T];
}
int DFS(int x,int flow)
{
if(x==T)
return flow;//到T点就停
int now=0;
for(int j=lnk[x]; j!=-1; j=nxt[j])
if(dep[x]+1==dep[son[j]]&&C[j]>F[j])
{
int y=DFS(son[j],min(flow,C[j]-F[j]));//选出最小流量
if(y>0)
{
F[j]+=y; //进行更新
F[j^1]-=y;
now+=y;
flow-=y;
if(!flow)
return now;
}
}
return now;
}
int Dinic()
{
int ans=0;
while(BFS())
while(int t=DFS(S,1e9))
ans+=t;
return ans;
}
int main()
{
memset(lnk,-1,sizeof(lnk));
n=read(),m=read();
S=read(),T=read();
for(int i=1; i<=m; i++)
{
int x=read(),y=read(),z=read();
add(x,y,z,0);
add(y,x,z,z);
}
printf("%d\n",Dinic());
return 0;
}
费用流
最大权闭合子图
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=105;
int n,m,T,s,t,Top,cur[MAXN],a[MAXN],Dep[MAXN],Ans,Sum;
struct Edge{
int tot,lnk[MAXN],son[MAXN<<1],nxt[MAXN<<1];
void clear(){memset(lnk,0,sizeof(lnk));tot=0;}
void Add(int x,int y){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;}
}S1,S2;
struct Flow{
int tot,lnk[MAXN],son[MAXN<<3],nxt[MAXN<<3],C[MAXN<<3];
void clear(){memset(lnk,-1,sizeof(lnk));tot=-1;}
void Add(int x,int y,int c){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;C[tot]=c;}
void Add_E(int x,int y,int c){Add(x,y,c),Add(y,x,0);}
}E;
void DFS1(int x,int fa){
if(fa) E.Add_E(x,fa,1<<30);
for(int j=S1.lnk[x];j;j=S1.nxt[j]) if(S1.son[j]!=fa) DFS1(S1.son[j],x);
}
void DFS2(int x,int fa){
if(fa) E.Add_E(x,fa,1<<30);
for(int j=S2.lnk[x];j;j=S2.nxt[j]) if(S2.son[j]!=fa) DFS2(S2.son[j],x);
}
int hd,tl,que[MAXN];
bool BFS(){
for(int i=s;i<=t;i++) Dep[i]=0;
hd=0;que[tl=1]=s;Dep[s]=1;
while(hd^tl){
int x=que[++hd];
for(int j=E.lnk[x];j^-1;j=E.nxt[j])
if(!Dep[E.son[j]]&&E.C[j]) Dep[E.son[j]]=Dep[x]+1,que[++tl]=E.son[j];
}
return Dep[t];
}
int DFS(int x,int flow){
if(x==t) return flow;
for(int &j=cur[x],y;j^-1;j=E.nxt[j])
if(Dep[x]+1==Dep[E.son[j]]&&E.C[j]>0&&(y=DFS(E.son[j],flow<E.C[j]?flow:E.C[j]))>0){E.C[j]-=y,E.C[j^1]+=y;return y;}
return 0;
}
int Dinic(){
int Sum=0;
while(BFS()){
for (int i=0;i<=t;i++) cur[i]=E.lnk[i];
while(int Add=DFS(s,1<<30)) Sum+=Add;
}
return Sum;
}
int main(){
freopen("theory.in","r",stdin);
freopen("theory.out","w",stdout);
scanf("%d",&T);
while(T--){
scanf("%d",&n);S1.clear(),S2.clear();Ans=0;Sum=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),Sum+=(a[i]>0?a[i]:0);
for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),S1.Add(x,y),S1.Add(y,x);
for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),S2.Add(x,y),S2.Add(y,x);
s=0,t=n+1;
for(int i=1;i<=n;i++){
E.clear();DFS1(i,0);DFS2(i,0);
for(int j=1;j<=n;j++) if(a[j]>0) E.Add_E(s,j,a[j]);else E.Add_E(j,t,-a[j]);
Ans=max(Ans,Sum-Dinic());
}
printf("%d\n",Ans);
}
return 0;
}