poj 3715 Blue and Red(二分图最大匹配匈牙利算法)
2012-03-01 21:23
766 查看
【题目大意】:给出n个士兵和m组关系,每个士兵均被划分在Blue组或者是Red组,m组关系描述的是士兵x,y直接是否是亲密关系。由于具备亲密关系的两个士兵被分在两个不同的组,那么对训练结果会产生不好的影响,问你最少去掉多少个士兵能够避免掉这种影响。并输出字典序最小的方案。
【解题思路】:题目一看下来,第一感觉就是写个二分图的最大匹配,所以一开始加了个源点和汇点就敲了个网络流。最大匹配是搞定了~问题是方案不会搞,所以yy了一下~想想自己没写过匈牙利算法就试一下吧,顺便学学。匈牙利算法是利用dfs寻找增广路径来确定最大匹配的。因为题目要求的是字典序最小,因此我们不妨从0~n-1进行枚举,删除该点后对新的图跑一次匈牙利算法,得到的新的增广路,观察新的增广路径是否变小,若变小则说明此点必在答案中。
【匈牙利算法】:摘自网络:
匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。
假设:M是G的一个匹配。
M-交错路:p是G的一条通路,如果p中的边为属于M中的边与不属于M但属于G中的边交替出现,则称p是一条M-交错路。
M-饱和点:对于v∈V(G),如果v与M中的某条边关联,则称v是M-饱和点,否则称v是非M-饱和点。
M-可增广路:p是一条M-交错路,如果p的起点和终点都是非M-饱和点,则称p为M-可增广路。(不要和流网络中的增广路径弄混了)
增广路的定义(也称增广轨或交错轨):
若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。
由增广路的定义可以推出下述三个结论:
1-P的路径个数必定为奇数,第一条边和最后一条边都不属于M。
2-将M和P进行取反操作可以得到一个更大的匹配M’。
3-M为G的最大匹配当且仅当不存在M的增广路径。
时间复杂度 邻接矩阵:最坏为O(n^3) 邻接表:O(mn) 空间复杂度 邻接矩阵:O(n^2) 邻接表:O(m+n)
【代码】:
【解题思路】:题目一看下来,第一感觉就是写个二分图的最大匹配,所以一开始加了个源点和汇点就敲了个网络流。最大匹配是搞定了~问题是方案不会搞,所以yy了一下~想想自己没写过匈牙利算法就试一下吧,顺便学学。匈牙利算法是利用dfs寻找增广路径来确定最大匹配的。因为题目要求的是字典序最小,因此我们不妨从0~n-1进行枚举,删除该点后对新的图跑一次匈牙利算法,得到的新的增广路,观察新的增广路径是否变小,若变小则说明此点必在答案中。
【匈牙利算法】:摘自网络:
匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。
假设:M是G的一个匹配。
M-交错路:p是G的一条通路,如果p中的边为属于M中的边与不属于M但属于G中的边交替出现,则称p是一条M-交错路。
M-饱和点:对于v∈V(G),如果v与M中的某条边关联,则称v是M-饱和点,否则称v是非M-饱和点。
M-可增广路:p是一条M-交错路,如果p的起点和终点都是非M-饱和点,则称p为M-可增广路。(不要和流网络中的增广路径弄混了)
增广路的定义(也称增广轨或交错轨):
若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。
由增广路的定义可以推出下述三个结论:
1-P的路径个数必定为奇数,第一条边和最后一条边都不属于M。
2-将M和P进行取反操作可以得到一个更大的匹配M’。
3-M为G的最大匹配当且仅当不存在M的增广路径。
时间复杂度 邻接矩阵:最坏为O(n^3) 邻接表:O(mn) 空间复杂度 邻接矩阵:O(n^2) 邻接表:O(m+n)
【代码】:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <vector> #include <queue> #include <algorithm> using namespace std; #define maxn 300 #define maxm 21000 struct edge{ int u,v; int next; }; int eh[maxn],tot,ans; int T,n,m; edge et[maxm]; bool visit[maxn]; int match[maxn]; int po[maxn]; void addd(int u,int v){ edge E = {u,v,eh[u]}; et[tot] = E, eh[u] = tot++; } void addedge(int u,int v){ addd(u,v); } bool dfs(int u) { for (int i = eh[u]; i != -1; i = et[i].next){ if (!visit[et[i].v] && po[et[i].v]==1){ visit[et[i].v]=true; if (match[et[i].v] == -1 || dfs(match[et[i].v])) { match[et[i].v] = u; return true; } } } return false; } int Match() { int cnt = 0; memset(match, -1, sizeof (match)); for (int u = 0; u < n; u++) { memset(visit, false, sizeof (visit)); if (!po[u] && dfs(u)) cnt++; } return cnt; } void solve(){ int anss[maxn]; int cnt=0; for(int i=0; i<n; i++){ po[i]=po[i]^1; int tmp=Match(); if(tmp<ans){ ans=tmp; anss[cnt++]=i; } else{ po[i]=po[i]^1; } } printf("%d",cnt); for(int i=0;i<cnt;i++){ printf(" %d",anss[i]); } printf("\n"); } int main(){ scanf("%d", &T); while (T--){ scanf("%d%d",&n,&m); int tmp; for (int i=0; i<n; i++){ scanf("%d",&tmp); po[i]=tmp; } int x,y; tot=0; memset(eh,-1,sizeof(eh)); for (int i=0; i<m; i++){ scanf("%d%d",&x,&y); if (po[x]!=po[y]){ if (po[x]==0) addedge(x,y); else addedge(y,x); } } ans=Match(); solve(); } }
相关文章推荐
- poj 3715 Blue and Red(二分图最大匹配+字典序输出)
- poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
- POJ1274:The Perfect Stall(二分图最大匹配 匈牙利算法)
- poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
- POJ 1274 The Perfect Stall (二分图最大匹配入门题,匈牙利算法)
- POJ 1469 COURSES (二分图最大匹配 匈牙利算法)
- 求解二分图的最大匹配的匈牙利算法---POJ 1325 Machine Schedule
- (模板题)poj 3041 Asteroids(二分图的最大匹配匈牙利算法)
- POJ 1469 COURSES【匈牙利算法入门 二分图的最大匹配 模板题】
- 二分图最大匹配匈牙利算法(poj)3041(模板)
- poj3020 二分图最大匹配(匈牙利算法)
- POJ1469(匈牙利算法求二分图最大匹配)
- POJ-3041 匈牙利算法 二分图最大匹配
- POJ 1469 COURSES【匈牙利算法入门 二分图的最大匹配 模板题】
- POJ1274 The Perfect Stall [二分图最大匹配 匈牙利算法]
- poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
- POJ1469[COURSES] 二分图最大匹配 匈牙利算法
- POJ 1469 COURSES(匈牙利算法二分图最大匹配)
- poj - 3041 Asteroids (二分图最大匹配+匈牙利算法)
- 二分图最大匹配(匈牙利算法) POJ 3041 Asteroids