poj 2724 Purifying Machine (最小边覆盖)
来源:互联网 发布:react.js ui 编辑:程序博客网 时间:2024/06/05 18:31
题意具体说什么没怎么看。
大致是说,m个n位的二进制数,有的含有*(一个数最多含1个),含*的可以用0或者1代替,即含*的同时表示两个二进制数。现在可以用任意的n位二进制数去覆盖这m个二进制数,如果存在两个二进制数,只有一位对应位上的数字不同,那么可以用一个二进制数去覆盖这两个。问最少使用多少个二进制数可以覆盖所有的这m个二进制数。
覆盖的过程可以看做匹配的过程。由此想到用图论来解决此题。
建图:
1、对于给出的m个数,如果含有*,则将其拆为两个二进制数。标记并记录出现的不同二进制数,设个数为nn。
2、对于这nn个数,将其拆为2*nn个点,如果某两个数之间恰有1位对应位不同,则该两个数之间连一条边。
3、求一次最大匹配。对于匹配的两个点,可以只用1个二进制数(或者说1条边)去覆盖,其余的各用1个。问题转化为最小边覆盖问题,总数即为nn减去最大匹配数/2(进行了拆点,匹配数增加1倍)
技巧:
关于判断两个十进制数对应的二进制数是否恰有1位对应位上的数字不同。
设两个十进制数为a,b
令c=a^b
如果c=0,说明a与b相等
若c!=0,则c对应的二进制位中的1代表了a、b对应二进制位上的数字不同。
如果仅有1位不同,则c对应的二进制位上,只有1个1。即有c&(c-1)=0
因此,令c=a^b
判断c&&(c&(c-1))是否为1即可。若为1,则恰有1位不同。
#include<iostream>#include<vector>#include<cstdio>#include<cstring>using namespace std;#define N (1<<10)bool T[N],M[N],Map[N][N];int nn,Left[N],n,m;char s[15];int match(int u){ for(int i=0;i<nn;++i){ if(Map[u][i]&&!T[i]){ T[i]=1; if(!Left[i]||match(Left[i])){ Left[i]=u; return 1; } } } return 0;}vector<int> vec;void toint(){ int ans=0,a=1; for(int i=n-1;i>=0;--i){ if(s[i]=='1') ans+=a; a<<=1; } if(!M[ans]){ M[ans]=1; vec.push_back(ans); }}bool judge(int x,int y){ int c=x^y; if(c&&(c&(c-1))==0) return 1; return 0;}int main(){ int i,j; while(~scanf("%d%d",&n,&m)&&(n+m)){ memset(M,0,sizeof(M)); memset(Map,0,sizeof(Map)); memset(Left,0,sizeof(Left)); vec.clear(); for(i=0;i<m;++i){ scanf("%s",s); for(j=0;j<n;++j) if(s[j]=='*') break; if(j<n){ s[j]='0'; toint(); s[j]='1'; toint(); }else toint(); } nn=vec.size(); for(i=0;i<nn;++i) for(j=0;j<nn;++j) if(judge(vec[i],vec[j])) Map[i][j]=1; int ans=0; for(i=0;i<nn;++i){ for(j=0;j<nn;++j) T[j]=0; ans+=match(i); } printf("%d\n",nn-ans/2); } return 0;}
0 0
- poj 2724 Purifying Machine (最小边覆盖)
- poj 2724 Purifying Machine 最小路径覆盖
- POJ 2724 Purifying Machine
- POJ-2724-Purifying Machine
- POJ 2724 Purifying Machine
- POJ2724 Purifying Machine二分图,最小边覆盖
- POJ2724 Purifying Machine【二分图最小边覆盖】
- poj 2724 Purifying Machine 二分匹配
- POJ 2724 Purifying Machine 已翻译
- 2724 Purifying Machine //MAXMATCH
- POJ 2724 Purifying Machine (二分图最大独立集Hungary)
- 【二分图+最大匹配】北大 poj 2724 Purifying Machine
- poj 2724 Purifying Machine 二分图最大匹配
- POJ 2724 Purifying Machine(二分图最大匹配)
- POJ 2724 Purifying Machine(最大独立集)
- POJ - 2724 Purifying Machine 二分图 最大匹配
- POJ 2724 Purifying Machine(二分图最大匹配)
- poj 2724 Purifying Machine(二分图最大匹配)
- LeetCode——Find Minimum in Rotated Sorted Array
- struct&typedef函数学习笔记
- 3Sum Closest
- 凸优化:ADMM(Alternating Direction Method of Multipliers)交替方向乘子算法系列之八: Distributed Model Fitting
- 260 数数小木块
- poj 2724 Purifying Machine (最小边覆盖)
- 【Python 学习手册笔记】介绍Python对象类型
- logback实用配置示例
- codeforce 86D Powerful array 莫对算法
- HttpClient 与 HtmlParser 简介
- [转]榨干 PHP,不得不转的一篇PHP使用技巧!
- Flatten Binary Tree to Linked List
- 凸优化:ADMM(Alternating Direction Method of Multipliers)交替方向乘子算法系列之九: Nonconvex Problems
- [转]开发大型高负载类网站应用的几个要点