dinic 算法
时间复杂度 O(n*n*e)
1 struct node{ 2 int u,v,next,c; 3 }edge[maxn<<1]; 4 int head[maxn]; 5 int cnt,dis[maxn],n,m,ans; 6 7 void init(){ 8 memset(head,-1,sizeof(head)); 9 cnt=0; 10 memset(dis,-1,sizeof(dis)); 11 ans=0; 12 } 13 void add(int a,int b,int c){ 14 edge[cnt].u=a; 15 edge[cnt].v=b; 16 edge[cnt].c=c; 17 edge[cnt].next=head[a]; 18 head[a]=cnt++; 19 } 20 bool bfs(){ 21 memset(dis,-1,sizeof(dis)); 22 queue<int>q; 23 dis[1]=0; 24 q.push(1); 25 int i,cur; 26 while(!q.empty()) { 27 cur=q.front(); 28 q.pop(); 29 for (int i=head[cur];i!=-1;i=edge[i].next){ 30 if(dis[edge[i].v]==-1&&edge[i].c>0){ 31 dis[edge[i].v]=dis[cur]+1; 32 q.push(edge[i].v); 33 } 34 } 35 } 36 if(dis[m]<0) return 0; 37 return 1; 38 } 39 int fnd(int x,int low){ 40 int a; 41 if(x==m) return low; 42 for (int i=head[x];i!=-1;i=edge[i].next){ 43 int v=edge[i].v; 44 if(dis[v]==dis[x]+1&&edge[i].c>0&&(a=fnd(v,min(low,edge[i].c)))){ 45 edge[i].c-=a; 46 edge[i^1].c+=a; 47 return a; 48 } 49 } 50 return 0; 51 } 52 void Dinic(){ 53 int temp; 54 while(bfs()){ 55 temp=fnd(1,inf); 56 ans+=temp; 57 } 58 printf("%d ",ans); 59 } 60 61 各种优化: 62 63 #include <iostream> 64 #include <cstdio> 65 #include <cstring> 66 #include <queue> 67 #define inf 0x3f3f3f3f3f3f3f3f 68 #define ll long long 69 #define MAXN 10005 70 using namespace std; 71 int n,m;//点数、边数 72 int sp,tp;//原点、汇点 73 struct node 74 { 75 int v,next; 76 ll cap; 77 }mp[MAXN*10]; 78 int pre[MAXN],dis[MAXN],cur[MAXN];//cur为当前弧优化,dis存储分层图中每个点的层数(即到原点的最短距离),pre建邻接表 79 int cnt=0; 80 void init()//不要忘记初始化 81 { 82 cnt=0; 83 memset(pre,-1,sizeof(pre)); 84 } 85 void add(int u,int v,int w)//加边 86 { 87 mp[cnt].v=v; 88 mp[cnt].cap=w; 89 mp[cnt].next=pre[u]; 90 pre[u]=cnt++; 91 } 92 bool bfs()//建分层图 93 { 94 memset(dis,-1,sizeof(dis)); 95 queue<int>q; 96 while(!q.empty()) 97 q.pop(); 98 q.push(sp); 99 dis[sp]=0; 100 int u,v; 101 while(!q.empty()) 102 { 103 u=q.front(); 104 q.pop(); 105 for(int i=pre[u];i!=-1;i=mp[i].next) 106 { 107 v=mp[i].v; 108 if(dis[v]==-1&&mp[i].cap>0) 109 { 110 dis[v]=dis[u]+1; 111 q.push(v); 112 if(v==tp) 113 break; 114 } 115 } 116 } 117 return dis[tp]!=-1; 118 } 119 ll dfs(int u,ll cap)//寻找增广路 120 { 121 if(u==tp||cap==0) 122 return cap; 123 ll res=0,f; 124 for(int &i=cur[u];i!=-1;i=mp[i].next) 125 { 126 int v=mp[i].v; 127 if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,mp[i].cap)))>0) 128 { 129 mp[i].cap-=f; 130 mp[i^1].cap+=f; 131 res+=f; 132 if(res==cap) 133 return cap; 134 } 135 } 136 if(!res) 137 dis[u]=-1; 138 return res; 139 } 140 ll dinic() 141 { 142 ll ans=0; 143 while(bfs()) 144 { 145 for(int i=1;i<=n;i++) 146 cur[i]=pre[i]; 147 ans+=dfs(sp,inf); 148 } 149 return ans; 150 } 151 int main() 152 { 153 154 return 0; 155 }
当前弧优化:
#include <cstdio> #include <cstring> #include <algorithm> #include <functional> #include <queue> #include <vector> using namespace std; const int maxn=1e5+10,inf=0x7fffffff; int n,m,f,e,s,t; struct Edge{ int u,v,c,flow; Edge(int a,int b,int cc,int f):u(a),v(b),c(cc),flow(f){} }; struct Dinic{ int s,t; vector<Edge>edges; vector<int>pre[maxn]; bool vis[maxn]; int dis[maxn]; int cur[maxn]; void init(){ for (int i=0;i<=n+1;i++) pre[i].clear(); edges.clear(); } void AddEdge(int a,int b,int c){ edges.push_back(Edge(a,b,c,0)); edges.push_back(Edge(b,a,0,0)); int mm=edges.size(); pre[a].push_back(mm-2); pre[b].push_back(mm-1); } bool bfs(){ memset(vis,false,sizeof(vis)); queue<int>q; q.push(s); vis[s]=1; dis[s]=0; while(!q.empty()){ int x=q.front();q.pop(); for (int i=0;i<pre[x].size();i++){ Edge &e=edges[pre[x][i]]; if(!vis[e.v]&& e.c>e.flow){ dis[e.v]=dis[x]+1; vis[e.v]=1; q.push(e.v); } } } return vis[t]; } int dfs(int x,int cap){ if(x==t||cap==0) return cap; int f,flow=0; for (int &i=cur[x];i<pre[x].size();i++){ cur[x]=i; Edge &e=edges[pre[x][i]]; if(dis[e.v]==dis[x]+1 && (f=dfs(e.v,min(cap,e.c-e.flow)))){ e.flow+=f; edges[pre[x][i]^1].flow-=f; flow+=f; cap-=f; if(cap==0) break; } } return flow; } int Maxflow(int s,int t){ this->s=s; this->t=t; int flow=0; while(bfs()) { memset(cur,0,sizeof(cur)); flow+=dfs(s,inf); } return flow; } }dc;
EK算法模板 算法复杂度 n*m*m (n为点数,m为边数) 源点 1, 汇点 n。
const int maxn=310,inf=0x7fffffff; int pre[maxn],mat[maxn][maxn]; bool vis[maxn]; int n,m; int Augment(){ int v; bool fnd=false; memset(pre,0,sizeof(pre)); memset(vis,false,sizeof(vis)); pre[1]=0; vis[1]=1; deque<int>q; q.push_back(1); while(!q.empty()){ v=q.front(); q.pop_front(); for (int i=1;i<=m;i++){ if(mat[v][i]>0&&!vis[i]){ //找到能走且为未走过的边 vis[i]=1; pre[i]=v; if(i==m){ fnd=1; q.clear(); break; } else q.push_back(i); } } } if(!fnd) return 0; v=m; int mi=inf; while(pre[v]){ mi=min(mi,mat[pre[v]][v]); v=pre[v]; } v=m; while(pre[v]){ mat[pre[v]][v]-=mi; mat[v][pre[v]]+=mi; v=pre[v]; } return mi; }
参考博客:
https://blog.csdn.net/lxy767087094/article/details/53606891
https://blog.csdn.net/hitwhacmer1/article/details/47019789
http://acm.pku.edu.cn/summerschool/gw_netflow.pdf
http://www.cnblogs.com/jianrenfang/p/7253715.html