二分图/网络流/最小割/最大流/最小费用最大流等等 模板
Posted passione-123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图/网络流/最小割/最大流/最小费用最大流等等 模板相关的知识,希望对你有一定的参考价值。
二分图匹配:
1.匈牙利算法 O(n * m) n为二分图左侧点数 m为二分图右侧点数
#include<bits/stdc++.h> using namespace std; const int N=1e7; struct node{ int from,to,nxt; }e[N]; int head[N],cnt; int n; int v[N],ans,A,B,d[N]; void add(int from,int to){ e[++cnt].nxt=head[from]; e[cnt].from=from; e[cnt].to=to; head[from]=cnt; return; } bool ok(int from){ for(int i=head[from];i;i=e[i].nxt){ int to=e[i].to; if(!v[to]){ v[to]=1; if(d[to]==-1||ok(d[to])){ d[to]=from; return 1; } } } return 0; } int main(){ scanf("%d%d%d",&A,&B,&n); for(int i=1;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); if(x>A||y>B)continue; add(x,y); } memset(d,-1,sizeof d); for(int i=1;i<=A;i++){ for(int j=1;j<=B;j++)v[j]=0; if(ok(i))ans++; } printf("%d",ans); }
2.Dinic O(n * √m) n,m含义同上
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=3000010; int s,t,n,m,x,y,z,maxflow,deep[N],A,B; struct Edge{ int next,to,w; }e[N]; int cnt=-1,head[N]; queue<int >q; void add(int from,int to,int w){ e[++cnt].next=head[from]; e[cnt].to=to; e[cnt].w=w; head[from]=cnt; } bool bfs(int s,int t){ memset(deep,0x3f,sizeof deep); while(!q.empty())q.pop(); deep[s]=0; q.push(s); while(!q.empty()){ int from=q.front(); q.pop(); for(int i=head[from];i!=-1;i=e[i].next){ if(deep[e[i].to]==inf&&e[i].w){ deep[e[i].to]=deep[from]+1; q.push(e[i].to); } } } if(deep[t]<inf)return 1; else return 0; } int dfs(int from,int t,int limit){ if(!limit||from==t)return limit; int flow=0,f; for(int i=head[from];i!=-1;i=e[i].next){ int to=e[i].to; if(deep[to]==deep[from]+1&&(f=dfs(to,t,min(limit,e[i].w)))){ flow+=f; limit-=f; e[i].w-=f; e[i^1].w+=f; if(!limit)break; } } return flow; } void dinic(int s,int t){ while(bfs(s,t)){ maxflow+=dfs(s,t,inf); } } int main(){ memset(head,-1,sizeof head); scanf("%d%d%d",&A,&B,&m); s=0; t=A+B+1; for(int i=1;i<=A;i++){ add(s,i,1); add(i,s,0); } for(int i=A+1;i<=A+B;i++){ add(i,t,1); add(t,i,0); } for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); if(x>A||y>B)continue; y+=A; add(x,y,1); add(y,x,0); } dinic(s,t); printf("%d",maxflow); return 0; }
网络流:
1.Dinic O(n2 * m) n为点数 m为边数
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; int s,t,n,m,x,y,z,maxflow,deep[302000]; struct Edge{ int next,to,w; }e[305000]; int cnt=-1,head[300500],cur[300500]; queue<int >q; void add(int from,int to,int w){ e[++cnt].next=head[from]; e[cnt].to=to; e[cnt].w=w; head[from]=cnt; } bool bfs(int s,int t){ memset(deep,0x3f,sizeof deep); while(!q.empty())q.pop(); deep[s]=0; q.push(s); while(!q.empty()){ int from=q.front(); q.pop(); for(int i=head[from];i!=-1;i=e[i].next){ if(deep[e[i].to]==inf&&e[i].w){ deep[e[i].to]=deep[from]+1; q.push(e[i].to); } } } if(deep[t]<inf)return 1; else return 0; } int dfs(int from,int t,int limit){ if(!limit||from==t)return limit; int flow=0,f; for(int i=head[from];i!=-1;i=e[i].next){ int to=e[i].to; if(deep[to]==deep[from]+1&&(f=dfs(to,t,min(limit,e[i].w)))){ flow+=f; limit-=f; e[i].w-=f; e[i^1].w+=f; if(!limit)break; } } return flow; } void dinic(int s,int t){ while(bfs(s,t)){ maxflow+=dfs(s,t,inf); } } int main(){ memset(head,-1,sizeof head); scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,0); } dinic(s,t); printf("%d",maxflow); return 0; }
以上是关于二分图/网络流/最小割/最大流/最小费用最大流等等 模板的主要内容,如果未能解决你的问题,请参考以下文章