poj 2724
来源:互联网 发布:吉林大学校网络教育 编辑:程序博客网 时间:2024/06/03 23:11
这个题比较有意思,我单独开一个来写一写
题意:
题意:迈克有一台可以净化奶酪的机器,用二进制表示净化的奶酪的编号。但是,在某些二进制串中可能包含有‘*'。例如01*100,'*'其实就代表可以取0,1两种情况--> 010100 和011100。现在由于迈克不小心,他以同样的方式弄脏了某些奶酪,问你最少用多少次操作就可以把弄脏的奶酪全净化好。(没有被弄脏过的奶酪不能净化。弄脏过的奶酪可以多次净化。)
思路:
也就是给你一些不同的(判重之后)二进制串,每个串可以通过1次操作净化,也可以把两个只有1位不同的串通过1次操作联合净化.要我们求最少的操作次数.
我们把所有串按其中1的个数和是奇还是偶分成左右两个点集.
对于任意两个串,如果他们只有1位不同,那么就在他们之间连接一条无向边.(这两个串一定分别属于不同的点集)
由于串的总数是固定的,且一个串可以通过单独净化也可以通过联合净化.而我们向让净化的次数最少,我们自然想联合净化(即一次可以净化两个串)的次数尽量多了. 那么我们最多可以进行多少次联合净化呢? 这个数值==我们建立二分图的最大匹配边数.(想想是不是,因为一个串最多只能被净化一次)
假设总的不同串有n个,我们建立二分图的最大匹配数(即联合净化最大次数)为ans,那么我们总共需要n-ans次净化即可.(想想为什么)
当然本题也可以不用把串特意分成左右点集(本程序实现就是用的这种方式:未分左右点集),我们只需要把原图翻倍,然后求翻倍图的最大匹配数ans,最后用n-ans/2即可.
这个题中有很多位运算的有意思的东西
详见代码
#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>#include<cmath>using namespace std;//顶点编号从0开始的const int MAXN=3000+50;int uN,vN;//u,v数目int g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];int num[MAXN];bool dfs(int u)//从左边开始找增广路径{ int v; for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改 if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) {//找增广路,反向 linker[v]=u; return true; } } return false;//这个不要忘了,经常忘记这句}int hungary()//xiongyali{ int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res;}//******************************************************************************/int main(){ int n,m; char str[50]; while(~scanf("%d%d",&n,&m)&&(m+n)) { memset(g,0,sizeof(g)); memset(num,0,sizeof(num)); int cnt=0; while(m--){ cnt++; scanf("%s",&str); int pos=-1; for(int i=0;i<n;i++){ if(str[i]=='*'){pos=i;continue;} num[cnt]|=(str[i]-'0')<<i; } if(pos!=-1){ cnt++; num[cnt]=(num[cnt-1]|(1<<pos)); } } sort(num+1,num+cnt+1); num[0]=-1; int i,j; for (j=0,i=1;i<=cnt;i++) { if (num[j]!=num[i]) num[++j] = num[i]; } cnt=j; //cout<<cnt<<endl; for(i=1;i<=cnt;i++) for(j=1;j<=cnt;j++){ int c=num[i]^num[j]; if(c&&((c&(c-1))==0))g[num[i]][num[j]]=1; } uN=vN=2050; int ans=cnt-hungary()/2; printf("%d\n",ans); } return 0;}
0 0
- poj 2724
- POJ 2724 Purifying Machine
- poj 2724 二分匹配
- POJ-2724-Purifying Machine
- POJ 2724 Purifying Machine
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- 华为Mate8石墨烯电池成亮点 5只股有炒作预期
- 单片机:c语言实现秒表计数(按键开始,结束,重置)
- socket阻塞与非阻塞模式
- EMC trainning杂谈
- poj 2724
- 网络爬虫:基于对象持久化实现爬虫现场快速还原
- PP后台配置-定义工作中心标准值
- 【树链剖分】[BZOJ 4196][NOI 2014]软件包管理器
- tomcat那些事
- 【数据结构与算法】 队列——队列的应用举例
- PP后台配置-定义工作中心标准值
- iOS 点击UIButton切换数组元素
- Android toolbar添加SearchView混淆打包成功后访问出错