POJ 2724 Purifying Machine(二分图最大匹配)
来源:互联网 发布:手机网站建站之星源码 编辑:程序博客网 时间:2024/06/05 20:35
题意:给出m串长度为n的01串。有些串中可能包含*,这样的串可以表示两个串,*为1 和*为0。重复的算一种。现在我们需要消灭掉所有的01串,消灭方式有两种:
1:一次消灭一个串。
2:如果两个串的差别只有一位的话可以同时消灭这两个串。
问最少多少次操作可以消灭所有的01串
思路:也就是给你一些不同的(判重之后)二进制串,每个串可以通过1次操作消去,也可以把两个只有1位不同的串通过1次操作一起消去.要我们求最少的操作次数.可以把所有串按其中1的个数和是奇还是偶分成左右两个点集.对于任意两个串,如果他们只有1位不同,那么就在他们之间连接一条无向边.(这两个串一定分别属于不同的点集),因为串的个数是固定的,并且一个串可以由单独的消去或者联合消去,而要让操作的次数最少,是不是可以联想到那道基站覆盖信号的题?其实是异曲同工的,需要操作的次数最少,那自然联合消去的次数要最多,那么只要求出这个最大值,然后n减去就是答案了,显然求出这个值用的最大匹配,当然也可以不用把串特意分成左右点集,我们只需要把原图翻倍,然后求翻倍图的最大匹配数ans,最后用n-ans/2即可.类似于POJ1466
#include<cstdio>#include<cstring>#include<vector>#include<set>#include<iostream>#include<string>using namespace std;const int maxn=1000+5;struct Max_Match{ int n,m;//左右点集大小,点从1开始编号 vector<int> g[maxn];//g[i]表示左边第i个点邻接的右边点的集合 bool vis[maxn];//vis[i]表示右边第i个点是否在本次match中被访问过 int left[maxn];//left[i]==j表右边第i个点与左边第j个点匹配,为-1表无点匹配 void init(int n) { this->n=n; // this->m=m; for(int i=1;i<=n;i++) g[i].clear(); memset(left,-1,sizeof(left)); } //判断从左u点是否可以找到一条增广路 bool match(int u) { for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(!vis[v]) { vis[v]=true; if(left[v]==-1 || match(left[v]))//找到增广路 { left[v]=u; return true; } } } return false; } //返回当前二分图的最大匹配数 int solve() { int ans=0;//最大匹配数 for(int i=1;i<=n;i++)//每个左边的节点找一次增广路 { memset(vis,0,sizeof(vis)); if(match(i)) ans++;//找到一条增广路,形成一个新匹配 } return ans; }}MM;struct Node{string s;}node[maxn];bool check(int i,int j){int num = 0;for (int ii = 0;ii<node[i].s.size();ii++){if (node[i].s[ii] != node[j].s[ii])num++;}return num == 1;}int main(){int n,m;while (scanf("%d%d",&n,&m)!=EOF && n){int num = 0;set<string> s;for (int i = 1;i<=m;i++){string temp;cin >> temp;if (temp.find("*") != -1){int pos = temp.find("*");string s1(temp),s2(temp);s1[pos]='0'; //*号填充为0s2[pos]='1'; //*号填充为1if (s.find(s1) == s.end()){s.insert(s1);node[++num].s = s1;}if (s.find(s2) == s.end()){s.insert(s2);node[++num].s = s2;}}else{if (s.find(temp) == s.end()){s.insert(temp);node[++num].s = temp;}}}MM.init(num);for (int i = 1;i<=num;i++)for (int j = 1;j<=num;j++){if (i!=j && check(i,j))MM.g[i].push_back(j);}printf("%d\n",num-MM.solve()/2);}}
0 0
- 【二分图+最大匹配】北大 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 二分匹配
- POJ 2724 Purifying Machine (二分图最大独立集Hungary)
- 【uva 1663】Purifying Machine 二分图匹配
- POJ 2724 Purifying Machine
- POJ-2724-Purifying Machine
- POJ 2724 Purifying Machine
- UVa 1663 - Purifying Machine(二分匹配)
- POJ 2724 Purifying Machine(最大独立集)
- poj - 1325 - Machine Schedule(二分图最大匹配)
- 【二分图|最大匹配】POJ-1325 Machine Schedule
- POJ 1325 Machine Schedule (最大二分匹配)
- POJ2724 Purifying Machine(二分图)
- 【Android进阶】Android面试题目整理与讲解
- org.hibernate.QueryException: query must begin with SELECT or FROM: delete
- python import 引入简单介绍
- C 和 C++ 的矩阵库
- 体育场
- POJ 2724 Purifying Machine(二分图最大匹配)
- 安卓开源项目框架合集
- 谈谈对单例的理解
- EventBus3.0使用总结
- java浮点数出现误差问题
- leetCode 328. Odd Even Linked List
- 上传AppStore遇到的奇葩问题之ERROR ITMS-90034: "Missing or invalid signature.
- 《Linxu优化之selinux详解以及运行级别详解》
- 河南第五届ACM省赛(最强DE 战斗力)(找规律+大数)