刷数论题也能碰到二分图。。。而且还是数据量大卡了匈牙利算法的。。。。
只好从bin神的博客里抄来了模版,先将就用着,以后有时间深究其原理。
/********************************************** 二分图匹配(Hopcroft-Carp的算法)。 初始化:g[][]邻接矩阵 调用:res=MaxMatch(); Nx,Ny要初始化!!! 时间复杂大为 O(V^0.5 E) 适用于数据较大的二分匹配 ***********************************************/ const int MAXN=3001; const int INF=1<<28; int g[MAXN][MAXN],Mx[MAXN],My[MAXN],Nx,Ny; int dx[MAXN],dy[MAXN],dis; bool vst[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 v=0;v<Ny;v++) if(g[u][v]&&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 v=0;v<Ny;v++) if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1) { vst[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||DFS(My[v])) { My[v]=u; Mx[u]=v; return 1; } } return 0; } int MaxMatch() { int res=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()) { memset(vst,0,sizeof(vst)); for(int i=0;i<Nx;i++) if(Mx[i]==-1&&DFS(i)) res++; } return res; }
下面代码将上面的代码的邻接矩阵改成了vector存图。
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; }