网络流之最大流和最小费用流
Posted 175426-hzau-zxjc-con
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流之最大流和最小费用流相关的知识,希望对你有一定的参考价值。
最大流
邻接矩阵
const int N=505; const int inf=0x3f3f3f3f; int mp[N][N],vis[N]; int dfs(int s,int t,int f) { if(s==t)return f; vis[s]=1; for(int i=1;i<=n;i++) { if(mp[s][i]>0&&!vis[i]) { int d=dfs(i,t,min(f,mp[s][i])); if(d>0) { mp[s][i]+=d; mp[i][s]-=d; return d; } } } } int maxflow(int s,int t) { int flow=0; while(1) { memset(vis,0,sizeof vis); int f=dfs(s,t,inf);//找到从s到t的增广路 if(f==0)return flow;//找不到了就回去 flow+=f;//找到一个流量为f的增广路 } }
邻接表
const int inf=0x3f3f3f3f; const int N=505; int vis[N]; struct Node { int to,cap,idx; NOde(){} NOde(int x,int y,int z):to(x),cap(y),idx(z); }; vector<NOde>node[N]; void add(int u,int v,int w) { node[u].push_back(NOde(v,w,node[v].size())); node[v].push_back(NOde(u,0,node[u].size()-1)); } int dfs(int s,int t,int f) { if(s==t)return f; vis[s]=1; for(int i=0;i<=node[s].size();i++) { Node &cur=node[s][i]; if(!vis[cur.to]&&cur.cap>0) { int tem=dfs(cur.to,t,min(f,cur.cap)); if(tem>0) { cur.cap-=tem; node[cur.to][cur.idx].cap+=tem; return tem; } } } return 0; } int maxflow(int s,int t) { int sum=0; while(1) { memeset(vis,0,sizeof vis); int flow=dfs(s,t,inf); if(flow==0)return sum; sum+=flow; } }
前向星
const int maxn=1005; const int N=505; const int inf=0x3f3f3f3f; int tot,head[maxn]; bool vis[maxn]; struct Node { int to,cap,next; Node(){} Node(int x,int y,int z):to(x),cap(y),next(z); }node[N*N*2]; void add(int u,int v) { node[tot]=Node(v,1,head[u]); head[u]=tot++; nod[tot]=NOde(u,0,head[v]); head[v]=tot++; } void emp() { memeset(head,-1,sizeof head); tot=0; } int dfs(int s,int t,int f) { if(s==t)return f; vis[s]=true; for(int i=head[s];i!=-1;i=node[i].next) { Node &cur=node[i]; if(!vis[cur.to]&&cur.cap>0) { int tem=dfs(cur.to,t,min(f,cur.cap)); if(tem>0) { cur.cap-=tem; node[i^1].cap+=tem; return tem; } } } return 0; } int maxflow(int s,int t) { int sum=0; while(1) { memeset(vis,0,sizeof vis); int flow=dfs(s,t,inf); if(flow==0)return sum; sum+=flow; } }
EK
const int inf=0x3f3f3f3f; const int maxn=105; int c[maxn][maxn],f[maxn][maxn],p[maxn],a[maxn]; int bfs() { queue<int >q; memset(p,-1,sizeof p); memset(a,0,sizeof a); a[s]=inf; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=1;i<=t;i++) { if(!a[i]&&c[u][i]>f[u][i]) { p[i]=u; q.push(i); a[i]=min(a[u],c[u][i]-f[u][i]); } } if(a[t])break; } if(!a[t])return 0; for(int u=t;u!=s;u=p[u]) { f[p[u]][u]+=a[t]; f[u][p[u]]-=a[t]; } return a[t]; } int EK() { int sum=0; while(1) { int tmp=bfs(); if(tmp==0)return sum; sum+=tmp; } }
Dinic
const int inf=0x3f3f3f3f; const int maxn=405; int c[maxn][maxn],dep[maxn]; int s,t; bool bfs() { queue<int>q; memset(dep,-1,sizeof dep); dep[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=1;v<=t;v++) { if(c[u][v]>0&&dep[v]=-1) { dep[v]=dep[u]+1; q.push(v); } } } return dep[t]!=-1; } int dfs(int u,int flow) { if(u==t)return flow; int tmp; for(int v=1;v<=t;v++) { if(c[u][v]>0&&dep[v]=dep[u]+1&&(tmp=dfs(v,min(flow,c[u][v]))); { c[u][v]-=tmp; c[v][u]+=tmp; return tmp; } } return 0; } int Dinic() { int res=0; while(bfs()) { while(tmp=dfs(s,inf)) { res+=tmp; } } return res; }
最小费用流
SPFA
const int inf=0x3f3f3f3f; const int maxn=405; int c[maxn][maxn],dep[maxn]; int s,t; bool bfs() { queue<int>q; memset(dep,-1,sizeof dep); dep[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=1;v<=t;v++) { if(c[u][v]>0&&dep[v]=-1) { dep[v]=dep[u]+1; q.push(v); } } } return dep[t]!=-1; } int dfs(int u,int flow) { if(u==t)return flow; int tmp; for(int v=1;v<=t;v++) { if(c[u][v]>0&&dep[v]=dep[u]+1&&(tmp=dfs(v,min(flow,c[u][v]))); { c[u][v]-=tmp; c[v][u]+=tmp; return tmp; } } return 0; } int Dinic() { int res=0; while(bfs()) { while(tmp=dfs(s,inf)) { res+=tmp; } } return res; }
以上是关于网络流之最大流和最小费用流的主要内容,如果未能解决你的问题,请参考以下文章