【最大流,二分图匹配】【hdu2063】【过山车】
题意:裸的求二分图匹配
建立一个源点 连向一边所有的点 容量为1;
另外一边点都连向汇点 容量为1;
二分图的边容量也为1
源点汇点求一遍最大流即可
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #define oo 0x13131313 using namespace std; const int MAXN=2000+5; const int MAXM=10000+5; const int INF=0x3f3f3f3f; struct Edge { int to,next,cap,flow; void get(int a,int b,int c,int d) { to=a;next=b;cap=c;flow=d; } }edge[MAXM]; int tol; int head[MAXN]; int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; void init() { tol=0; memset(head,-1,sizeof(head)); } //单向图三个参数,无向图四个参数 void addedge(int u,int v,int w,int rw=0) { edge[tol].get(v,head[u],w,0);head[u]=tol++; edge[tol].get(u,head[v],rw,0);head[v]=tol++; } int sap(int start,int end,int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while(dep[start]<N) { if(u==end) { int Min=INF; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u = start; ans+=Min; continue; } bool flag=false; int v; for(int i=cur[u];i !=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } int Min=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if(u!=start) u=edge[pre[u]^1].to; } return ans; } int KK,MM,NN; void input() { int a,b; for(int i=1;i<=KK;i++) { scanf("%d%d",&a,&b); addedge(a,b+MM,1); } } void solve() { int ANS; for(int i=1;i<=MM;i++) { addedge(MM+NN+1,i,1); } for(int i=MM+1;i<=MM+NN;i++) { addedge(i,MM+NN+2,1); } ANS=sap(MM+NN+1,MM+NN+2,MM+NN+2); printf("%d\n",ANS); } void File() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); } int main() { // File(); while(cin>>KK>>MM>>NN&&KK) { init(); input(); solve(); } }