POJ 2724 Purifying Machine(最大独立集)

POJ 2724 Purifying Machine

题目链接

题意:这题题意有点没看懂。看了别人的题解,

给出m串长度为n的01串。

有些串中可能包括,这种串能够表示两个串,为1 和为0。

反复的算一种。比方题目中01

100

011

就代表了四个01串

001

101

100

011

如今我们须要消灭掉全部的01串,消灭方式有两种:

1一次消灭一个串。

2假设两个串的区别仅仅有一位的话能够同一时候消灭这两个串。

问最少多少次操作能够消灭全部的01串

思路:把存在的二进制数保存下来,然后去重。然后建边,二进制相差1位的连边。然后求最大独立集,n - 最大匹配数

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 2005;

int s[N], n, m;
char str[15];
vector<int> g[N];

int bitcount(int x) {
	return x == 0 ? x : bitcount(x>>1) + (x&1);
}

int left[N], vis[N];

bool dfs(int u) {
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (vis[v]) continue;
		vis[v] = 1;
		if (left[v] == -1 || dfs(left[v])) {
			left[v] = u;
			return true;
		}
	}
	return false;
}

int hungary() {
	int ans = 0;
	memset(left, -1, sizeof(left));
	for (int i = 0; i < n; i++) {
		memset(vis, 0, sizeof(vis));
		if (dfs(i)) ans++;
	}
	return ans;
}

int main() {
	while (~scanf("%d%d", &n, &m) && n) {
		n = 0;
		for (int i = 0; i < m; i++) {
			scanf("%s", str);
			int len = strlen(str);
			s[n] = 0;
			for (int j = len - 1; j >= 0; j--)
				s[n] = s[n] * 2 + (str[j] != '0');
			n++;
			for (int j = 0; j < len; j++) {
				if (str[j] == '*') {
					s[n] = s[n - 1];
					s[n] ^= (1<<j);
					n++;
				}
			}
		}
		sort(s, s + n);
		int tmp = 1;
		for (int i = 1; i < n; i++)
			if (s[i] != s[i - 1]) s[tmp++] = s[i];
		n = tmp;
		for (int i = 0; i < n; i++) {
			g[i].clear();
			for (int j = 0; j < i; j++) {
				if (bitcount(s[i]^s[j]) <= 1) {
					g[i].push_back(j);
					g[j].push_back(i);
				}
			}
		}
		printf("%d\n", n - hungary() / 2);
	}
	return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-11-04 18:34:57

POJ 2724 Purifying Machine(最大独立集)的相关文章

poj 2724 Purifying Machine

Purifying Machine Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5408   Accepted: 1575 Description Mike is the owner of a cheese factory. He has 2N cheeses and each cheese is given a binary number from 00...0 to 11...1. To keep his chee

poj 2724 Purifying Machine(二分图最大匹配)

题意: 有2^N块奶酪,编号为00...0到11..1. 有一台机器,有N个开关.每个开关可以置0或置1,或者置*.但是规定N个开关中最多只能有一个开关置*. 一旦打开机器的开关,机器将根据N个开关的状态对状态对应的编号的奶酪进行消毒. 例如:111 -->  对编号111的奶酪进行消毒.    说明:*代表0或1. 例如:1*1  -->  对编号为101和111的奶酪进行消毒. 现在有一些奶酪被污染了.给出这些奶酷的编号. 问最少需要几次对机器进行设定,使得所有的奶酪都被消毒. 思路: 一

POJ - 2724 Purifying Machine 二分图 最大匹配

题目大意:看了别人的题意: 给出m串长度为n的01串,如果某个串中包含'*'号的,那么这个串就可以变成两个串(因为'*'既可以表示0或者1) 比如字符串*01就可以表示成001,或者101 现在的任务是消除所有的串,给出消除串的规则如下: 1一次消灭一个串. 2如果两个串的差别只有一位的话可以同时消灭这两个串. 问至少需要多少次才能消灭这些串 解题思路:先将这些串去重,化成整数,这样就可以得到两个点集了,点集之间的关系就是一个操作能否消除掉两个串,如果可以的话,则这两个串就存在关系了 #incl

POJ 2455Secret Milking Machine(二分+网络流之最大流)

题目地址:POJ2455 手残真浪费时间啊..又拖到了今天才找出了错误..每晚两道题不知不觉又变回了每晚一道题...sad.. 第一次在isap中忘记调用bfs,第二次则是遍历的时候居然是从1开始遍历的...sad... 这题思路倒是很简单,就是有一个比较坑的地方,就是这里的重边要当两条边来用,以前受最短路什么的影响,直接把慢的删了,很明显不对...这里的两条重边都是可以走的. 建图思路是,将1当作源点,将n当作汇点.右边的地方就连边,注意是无向边.最后判断最大流是否等于道路条数.二分找最小值.

poj 1419 Graph Coloring_最大独立集

题目链接 题意:给出你一个无向图,然后对其中的点去上色, 只能上黑色和白色,要求是黑色点不能相邻,问最多能上多少黑色的顶点. 思路:点独立集:设无向图G=<V,E>,顶点集合V'是V的子集,若V'中的任意两个顶点都不相邻,则称V'为G的点独立集 这题求的是最大独立集 还有一个定理是最大独立集=补图的最大团 最大团=补图的最大独立集 #include<stdio.h> #include<string.h> #define MAXN 100 int n,map[MAXN][

POJ 1276 Cash Machine 背包题解

典型的多重背包的应用题解. 可以使用二进制优化,也可以使用记录当前物品的方法解,速度更加快. const int MAX_CASH = 100001; const int MAX_N = 11; int tbl[MAX_CASH], nums[MAX_N], bills[MAX_N], cash, n; int bag() { if (cash <= 0 || n <= 0) return 0; memset(tbl, 0, sizeof(int) * (cash+1)); for (int

poj 1276 Cash Machine (多重背包)

链接:poj 1276 题意:已知金额cash,给定几种不同面值的货币的数量及面值,求利用给定的货币可以凑成 小于等于cash的金额的最大值 分析:因为每种货币的面值及数量已知,可以将其转化为多重背包,背包的容量即为cash, 每个物品的价值及费用都为每种货币的面值. 多重背包可以转化为01背包,不过这样会超时,为了避免这样,可以转化为完全背包和二进制思想的01背包 #include<stdio.h> #include<string.h> int f[100010],v; int

POJ 2724 奶酪消毒机 二分匹配 建图 比较难想

Purifying Machine Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5004   Accepted: 1444 Description Mike is the owner of a cheese factory. He has 2N cheeses and each cheese is given a binary number from 00...0 to 11...1. To keep his chee

POJ 3692 Kindergarten(最大独立集)

[题目链接] http://poj.org/problem?id=3692 [题目大意] 男生相互之间都认识,女生相互之间也都认识, 一些男生和一些女生相互之间也认识,求找出最多的人参加派对, 他们相互之间都认识 [题解] 我们建认识图的反图,将相互之间不认识的连线, 那么问题转化为求这个图的最大独立集, 最大独立集答案为总点数减去最大匹配. [代码] #include <cstdio> #include <cstring> using namespace std; const i