SCL--二分匹配
2015-05-28 21:03:27
总结:
首先是跑得最快的 Hopcroft-Karp (这个算法是因为 hdu 2389 才学的..)
bool find(int p){ for(int i = first[p]; ~i; i = e[i].next){ int v = e[i].v; if(!vis[v] && dy[v] == dx[p] + 1){ vis[v] = 1; if(!my[v] || find(my[v])){ my[v] = p; mx[p] = v; return true; } } } return false; } int HK(){ memset(mx,0,sizeof(mx)); memset(my,0,sizeof(my)); int res = 0; while(1){ bool flag = false; while(!Q.empty()) Q.pop(); memset(dx,0,sizeof(dx)); memset(dy,0,sizeof(dy)); for(int i = 1; i <= m; ++i) if(!mx[i]) Q.push(i); while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = first[x]; ~i; i = e[i].next){ int v = e[i].v; if(!dy[v]){ dy[v] = dx[x] + 1; if(my[v]){ dx[my[v]] = dy[v] + 1; Q.push(my[v]); } else flag = true; } } } if(!flag) break; memset(vis,0,sizeof(vis)); for(int i = 1; i <= m; ++i) if(!mx[i] && find(i)) ++res; } return res; }
接着是经典的 Hungary:
bool find(int p){ for(int i = first[p]; ~i; i = e[i].next){ int v = e[i].v; if(used[v] == 0){ used[v] = 1; if(mat[v] == 0 || find(mat[v])){ mat[v] = p; tmat[p] = v; return true; } } } return false; } int Hungary(){ memset(mat,0,sizeof(mat)); memset(tmat,0,sizeof(tmat)); int res = 0; for(int i = 1; i <= N; ++i){ memset(used,0,sizeof(used)); if(find(i)) res++; } return res; }