【模板】网络流和匈牙利及二分图染色算法模板
并不全,仅含SAP算法和spfa+增广路,还有hungary。
SAP:(最大流问题)
int sap(int x,int flow) { if(x==n) return flow; int dlt=0,tmp; for(int it=la[x];it;it=nt[it]) { if(dis[en[it]]+1==dis[x]&&v[it]) { tmp = sap(en[it],min(flow-dlt,v[it])); dlt+=tmp; v[it]-=tmp; v[it^1]+=tmp; if(dis[S]>=n||dlt==flow) return dlt; } } if(dis[S]>=n) return dlt; cnt[dis[x]]--; if(!cnt[dis[x]]) dis[S]=n; dis[x]++; cnt[dis[x]]++; return dlt; } main() { int ans=0; while(dis[S]<n) { ans+=sap(S,inf); } }Hungary:(二分图匹配问题)
int vis[maxn],link[maxn]; bool hungary(int x,int id) { int ss=ve[x].size(); for(int i=0;i<ss;i++) { int en=ve[x][i]; if(vis[en]==id) continue; vis[en]=id; if((!link[en])||(hungary(link[en],id))) { link[en]=x; return true; } } return false; } main() { int ans=0; for(int i=1;i<=n;i++) ans+=hungary(i,i); }SPFA+增广路(费用流问题)(不要用dijstra,有负边!)
bool rd[maxn]; int dis[maxn],epath[maxn],path[maxn]; int mincost,maxflow; void addflow() { int flow=inf; for(int i=T;i!=S;i=path[i]) { flow=min(flow,v[epath[i]]); } maxnflow+=flow; mincost+=flow*dis[T]; for(int i=T;i!=S;i=path[i]) { v[epath[i]]-=flow; v[epath[i]^1]+=flow; } } void spfa(int x) { for(int i=1;i<=n;i++) { dis[i]=inf; path[i]=-1; epath[i]=-1; rd[i]=0; } dis[x]=path[x]=0; q.push(x); rd[x]=1; while(q.size()) { x=q.front(); q.pop(); rd[x]=0; for(int it=la[x];it;it=nt[it]) { if(v[it]&&dis[en[it]]>dis[x]+len[it]) { dis[en[it]]=dis[x]+len[it]; path[en[it]]=x; epath[en[it]]=it; if(!rd[en[it]]) { rd[en[it]]=1; q.push(en[it]); } } } } if(dis[T]<inf) return true; else return false; }二分图染色
bool dfs(int x) { for(int i=ve[x].size()-1;i>=0;i--) { if(!col[ve[x][i]]) { col[ve[x][i]] = 3-col[x]; if(!dfs(ve[x][i])) return false; } else if(col[ve[x][i]]==col[x]) return false; } return true; } for(int i=1;i<=2*n;i++) { if(!col[i]) { col[i] = 1; if(!dfs(i)) { flag=0;break ; } } }