[Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]
经典二分图匹配,可以用匈牙利算法,也可以用最大流
代码如下(Dinic):
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <queue> using namespace std; template<const int _n> struct Edge { struct Edge_base { int to,next,w; }e[_n]; int p[_n],cnt; void insert(const int x,const int y,const int z) { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; } int start(const int x) { return p[x]; } void clear() { cnt=1;memset(p,0,sizeof(p)); } Edge_base& operator[](const int x) { return e[x]; } }; int n,m,flow,SSS,TTT; int level[110],From[110],From_e[110]; Edge<310> e; bool Bfs(const int S) { int i,t; queue<int> Q; memset(level,0,sizeof(level)); memset(From,0,sizeof(From)); level[S]=1; Q.push(S); while(!Q.empty()) { t=Q.front(),Q.pop(); for(i=e.start(t);i;i=e[i].next) { if(!level[e[i].to] && e[i].w) { level[e[i].to]=level[t]+1; Q.push(e[i].to); From[e[i].to]=t; From_e[e[i].to]=i; if(e[i].to==TTT)goto End; } } } End: if(!level[TTT])return false; flow++; for(i=TTT;i!=SSS;i=From[i])e[From_e[i]].w--,e[From_e[i]^1].w++; return true; } int Dinic() { while(Bfs(SSS)); return flow; } int main() { freopen("flyer.in","r",stdin); freopen("flyer.out","w",stdout); int i,x,y; scanf("%d%d",&m,&n); m=m-n; while(scanf("%d%d",&x,&y)==2) { if(x>y)swap(x,y); e.insert(x,y,1); e.insert(y,x,0); } SSS=n+m+1,TTT=n+m+2; for(i=1;i<=n;++i) { e.insert(SSS,i,1); e.insert(i,SSS,0); } for(i=n+1;i<=m+n;++i) { e.insert(i,TTT,1); e.insert(TTT,i,0); } printf("%d\n",Dinic()); return 0; }
匈牙利代码:http://www.cnblogs.com/Ngshily/p/4988909.html