首页 > 其他 > 详细

二分图

时间:2019-06-10 19:02:55      阅读:103      评论:0      收藏:0      [点我收藏+]
//黑白二着色-bicoloring(判断是否为二分图)
int
color[maxn]; bool bipartite(int u){ for(int i = 0; i < g[u].size(); i++){ int v = g[u][i]; if(color[u] == color[v]) return false; if(!color[v]){ color[v] = 3 - color[u]; if(!bipartite(v)) return false; } } return true; }
//二分图的最大匹配
void
dfs(int x){ for(int i = 0; i < g[x].size(); i++){ int y = g[x][i]; if(!path[y]){ path[y] = 1; if(c[y] == -1 || dfs(c[y])){ c[y] = x; return true; } } } return false; } int main() { int ans = 0; memset(c, -1, sizeof(c)); for(int i=0; i < num_left; i++){ memset(path, 0, sizeof(path)); if(dfs(i)) ans++; } }
//二分图的最佳完美匹配(KM算法)
int
W[maxn][maxn],n; int Lx[maxn],Ly[maxn]; int left[maxn]; bool S[maxn],T[maxn]; bool match(int i){ S[i]=true; for(int j=1;j<=n;j++) if(Lx[i]+Ly[j]==W[i][j]&&!T[j]){ T[j]=true; if(!left[j]||match(left[j])){ left[j]=i; return true; } } return false; } void update(){ int a=1<<30; for(int i=1;i<=n;i++) if(S[i]) for(int j=1;j<=n;j++) if(!T[j]) a=min(Lx[i]+Ly[j]-W[i][j]); for(int i=1;i<=n;i++){ if(S[i]) Lx[i]-=a; if(L[i]) Ly[i]+=a; } } void KM(){ for(int i=1;i<=n;i++){ left[i]=Lx[i]=Ly[i]=0; for(int j=1;j<=n;j++) Lx[i]=max(Lx[i],W[i][j]); } for(int i=1;i<=n;i++){ for(;;){ for(int j=1;j<=n;j++) S[i]=T[j]=false; if(match(i)) break; else update(); } } }

 

二分图

原文:https://www.cnblogs.com/hanasaki/p/10999455.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!