标签:
二分图:
二分图中,顶点可以分为两个集合,每一条边的端点都分别位于这两个集合。
二分图的判定:
可以利用Bfs或者Dfs进行黑白染色,共享一条边的两点异色,检查一下是否存在矛盾即可。
相关题目:Hdu 2444 The Accomodation of Students
bfs代码:
1 void bfs (int s) 2 { 3 int p, q, zreo, one, num; 4 queue <int> Q; 5 zreo = 1; 6 one = vis[s] = 0; 7 Q.push(s); 8 while (!Q.empty()) 9 { 10 p = Q.front(); 11 Q.pop(); 12 num = (vis[p] + 1) % 2; 13 for (int i=0; i<G[p].size(); i++) 14 { 15 q = G[p][i]; 16 if (vis[q]!=-1 && num != vis[q]) 17 flag = 1; 18 if (vis[q]==-1) 19 { 20 Q.push(q); 21 vis[q] = num; 22 if (num == 0) 23 zreo ++; 24 else 25 one ++; 26 } 27 } 28 } 29 }
dfs代码:
1 void dfs (int u, int c, int &a, int &b) 2 { 3 b ++; 4 if (c) 5 a ++; 6 vis[u] = c; 7 for (int i=head[u]; i!=-1; i=edge[i].next) 8 { 9 int v = edge[i].to; 10 if (vis[v] == -1) 11 dfs(v, c^1, a, b); 12 } 13 }
二分图相关问题:
二分图最大匹配:匹配是二分图中边的集合,且集合中的任意边没有公共点,包含边数最多的匹配。
匈牙利算法模板:
1 bool Find (int u) 2 { 3 for (int i=head[u]; i!=-1; i=edge[i].next) 4 { 5 int v = edge[i].to; 6 if (!vis[v]) 7 { 8 vis[v] = 1; 9 if (!used[v] || Find(used[v])) 10 { 11 used[v] = u; 12 return true; 13 } 14 } 15 } 16 return false; 17 }
最小顶点覆盖:在二分图中寻找一个尽量小的点集,使图中每一条边至少有一个点在该点集中。
最小顶点覆盖 == 最大匹配。
反证法证明:假设当前存在一条两个端点都不在最小顶点覆盖点集中,那么这么光芒四射的边定可以增大最大匹配边集,与最大匹配矛盾,所以得证。
最小路径覆盖:在二分图中寻找一个尽量小的边集,使图中每一个点都是该边集中某条边的端点。
最小路径覆盖 == 顶点数 - 最大匹配。
证明:因为一条边最多可以包含两个顶点,所以我们选边的时候让这样的边尽量多,也就是说最大匹配的边集数目咯。剩下的点就只能一个边连上一个点到集合里啦。
最大独立集:在N个点中选出来一个最大点集,使这个点集中的任意两点之间都没有边。
最大独立集 == 顶点数 - 最大匹配。
证明:因为去掉最大匹配两端的顶点去掉以后,剩下的点肯定是独立集。我们再从每个匹配里面挑选出来一个点加入到独立集中,也是不会破坏原有独立集的独立性的。
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4695298.html