网络流算法
Dinic算法
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<vector> using namespace std; const int INF=1e9+7; const int maxn=205; int N,M,S,T; struct edge { int u,v,cap,flow; edge(int u=0,int v=0,int cap=0,int flow=0) :u(u),v(v),cap(cap),flow(flow){} }E[maxn*maxn]; int eid; //要初置为0 vector<int> G[maxn]; void init() { eid=0; for(int i=0;i<maxn;i++) G[i].clear(); } void AddEdge(int u,int v,int cap) { E[eid]=edge(u,v,cap,0); G[u].push_back(eid++); E[eid]=edge(v,u,0,0); G[v].push_back(eid++); } bool vis[maxn]; int d[maxn],cur[maxn]; queue<int> que; bool BFS() { memset(vis,false,sizeof(vis)); while(!que.empty()) que.pop(); vis[S]=true; d[S]=0; que.push(S); while(!que.empty()) { int u=que.front(); que.pop(); int Size=G[u].size(); for(int i=0;i<Size;i++) { int id=G[u][i]; edge& e=E[id]; int v=e.v; if(!vis[v]&&e.cap>e.flow) { vis[v]=true; d[v]=d[u]+1; que.push(v); } } } return vis[T]; } int DFS(int u,int a) { if(u==T||a==0) return a; int ret=0,f; int Size=G[u].size(); for(int& i=cur[u];i<Size;i++) { int id=G[u][i]; edge& e=E[id]; int v=e.v; if(d[u]+1==d[v]&&(f=DFS(v,min(a,e.cap-e.flow)))>0) { ret+=f; e.flow+=f; E[id^1].flow-=f; a-=f; if(a==0) break; } } return ret; } int MaxFlow(int s,int t) { S=s; T=t; int ret=0; while(BFS()) { memset(cur,false,sizeof(cur)); ret+=DFS(S,INF); } return ret; }
EK算法
struct edge { int from,to,cap,flow; edge(int from=0,int to=0,int cap=0,int flow=0) :from(from),to(to),cap(cap),flow(flow){} }; vector<edge> save; vector<int> G[105]; void addedge(int from,int to,int cap,int flow) { save.push_back(edge(from,to,cap,flow)); save.push_back(edge(to,from,0,flow)); int id=save.size(); G[from].push_back(id-2); G[to].push_back(id-1); } int add[105],fa[105]; int MaxFlow(int be,int en) { int ret=0; while(true) { memset(add,0,sizeof(add)); queue<int> que; que.push(be); add[be]=INF; while(!que.empty()) { int from=que.front(); que.pop(); for(int i=0;i<G[from].size();i++) { edge e=save[G[from][i]]; int to=e.to,cap=e.cap,flow=e.flow; if(!add[to]&&cap>flow) { fa[to]=G[from][i]; add[to]=min(add[from],cap-flow); que.push(to); } } if(add[en]) break; } if(!add[en]) break; for(int st=en;st!=be;st=save[fa[st]].from) { save[fa[st]].flow+=add[en]; save[fa[st]^1].flow-=add[en]; } ret+=add[en]; } return ret; }
最小费最大流算法
struct edge { int u,v; int cap,flow,cost; edge(int u=0,int v=0,int cap=0,int flow=0,int cost=0) :u(u),v(v),cap(cap),flow(flow),cost(cost){} }save[4*maxn*maxn]; struct MFMC { int n,edge_num; vector<int> G[maxn]; void init(int nn) { n=nn; edge_num=0; for(int i=0;i<=n;i++) G[i].clear(); } void addedge(int u,int v,int cap,int cost) { int a=edge_num++; int b=edge_num++; save[a]=edge(u,v,cap,0,cost); save[b]=edge(v,u,0,0,-cost); G[u].push_back(a); G[v].push_back(b); } int add[maxn],C[maxn]; int fa[maxn]; bool inq[maxn]; void clr(int s) { for(int i=0;i<=n;i++) add[i]=0,inq[i]=false,C[i]=INF; add[s]=INF; inq[s]=true; C[s]=0; fa[s]=0; } int solve(int s,int t) { int cnt=0,ret=0; while(true) { clr(s); queue<int> que; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); inq[u]=false; int Size=G[u].size(); for(int i=0;i<Size;i++) { int edge_id=G[u][i]; edge& e=save[edge_id]; int v=e.v; int cap=e.cap,flow=e.flow,cost=e.cost; if(cap>flow&&C[v]>C[u]+cost) { C[v]=C[u]+cost; fa[v]=edge_id; add[v]=min(add[u],cap-flow); if(!inq[v]){ inq[v]=true; que.push(v); } } } } if(!add[t]) break; cnt+=add[t]; ret+=add[t]*C[t]; for(int st=t;st!=s;st=save[fa[st]].u) { int a=fa[st],b=fa[st]^1; save[a].flow+=add[t]; save[b].flow-=add[t]; } } return ret; } };