二分图(Hopcroft-Carp算法)
二分图(Hopcroft-Carp算法)
下面代码将上面的代码的邻接矩阵改成了vector存图。
顶点编号 u= 1~uN,v=uN+1~uN+vN,加边的时候加u到v的单向边就可以了,因此建图前要将原图分为u和v两个子图。
vector<int> G[maxn]; int Mx[maxn],My[maxn],Nx,Ny; int dx[maxn],dy[maxn],dis; bool vis[maxn]; bool searchP() { queue<int> q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=0;i<Nx;i++){ if(Mx[i]==-1){ q.push(i); dx[i]=0; } } while(!q.empty()){ int u=q.front(); q.pop(); if(dx[u]>dis) break; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(dy[v]==-1){ dy[v]=dx[u]+1; if(My[v]==-1) dis=dy[v]; else{ dx[My[v]]=dy[v]+1; q.push(My[v]); } } } } return dis!=INF; } bool dfs(int u) { for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(!vis[v]&&dy[v]==dx[u]+1){ vis[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||dfs(My[v])){ My[v]=u; Mx[u]=v; return true; } } } return false; } int MaxMatch() { int res=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()){ memset(vis,0,sizeof(vis)); for(int i=0;i<Nx;i++){ if(Mx[i]==-1&&dfs(i)) res++; } } return res; }
没有AC不了的题,只有不努力的ACMER!