经典二分图匹配,可以用匈牙利算法,也可以用最大流
代码如下(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