poj2724
Posted zhltao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2724相关的知识,希望对你有一定的参考价值。
poj2724
序
今天考试又炸了呢。
正文
题目链接 其实题目描述的十分不清楚。我瞪了十分钟愣是没看题。。但是后面发现,这不就是一个二分图最大匹配吗!
我们只要统计出被感染的奶酪数,然后看最多可以操作几次带 ‘*’ 的,就好了这个机器的操作简直耐人寻味,可以把二进制里只有以以一位不同的一起做。
10min
这什么东西打暴力吧(笑
20min
这不是一个二分图最大匹配吗。干
30min
转完了二进制。。怎么判呀。稍微想了想,可以这样 对于两个数 A,B,如果 A^B = C 这个C只有一位是 1, 咋办 - 1 之后异或不就完了,然后就发现事实上还要判一下 C 是不是0
然后怎么匹配,我们还是要把图的二分呀。咋二分?
35min
想到了如何二分图 ,根据每一个数二进制一的个数来二分,我们显然的可以知道,如果一的个数奇偶,他们肯定一起操作不了。
40min
干呀,裸的匈牙利上呀!
60min
不错样例过了,交一发试试。 TLE 啥回事,匈牙利会 T ?? 然后看了下 wyq 的记录 1907ms ,嗯,被卡常了。。然后跟 Singer 说匈牙利T了,要换ISAP..就开始写ISAP
70min
正写着ISAP.瞥了眼原来代码。。数组开小了。开大点,再交一发 WA 开始Debug
75min
p数组忘清零了。。交一发。 AC
代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define get getchar
#define put putchar
int read() { int x = 0; bool f = 0; char ch = get(); while(ch < '0' || ch >'9') { f = (ch == '-'); ch = get(); }while(ch <= '9' && ch >= '0') { x = (x << 1) + (x << 3) + (ch - '0'); ch = get(); }return f ? -x : x; }
void write(int x) { if(x < 0) { put('-'); x = abs(x); }if(x < 10) { put(x + 48); return; }write(x / 10); put(x % 10 + 48); }
#undef put
#undef get
char get() {char ch = getchar(); while(ch == '
' || ch == '
' || ch == ' ') { ch = getchar(); } return ch; }
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
using namespace std;
const int Maxn = 11, Max = Maxn << 7;
int n, m, tmp, ops, cou[Max], num, ans, h[Max], cnt, p[Max], poi[Max];
char ch;
struct Edge {
int to, lac;
void insert(int x, int y) { to = y; lac = h[x]; h[x] = cnt++; }
}edge[Max * Max];
bool flag[Max];
bool find(int u) {
for(int i = h[u]; i != -1; i = edge[i].lac) {
int to = edge[i].to;
if(flag[to]) { continue; }
flag[to] = 1;
if(!p[to] || find(p[to])) {
p[to] = u;
return 1;
}
}
return 0;
}
bool ok(int i, int j) {
int c = poi[i] ^ poi[j];
return (c != 0) && !(c & (c-1));
}
int main() {
freopen("test.in", "r", stdin);
while(true) {
n = read(); m = read(); ans = 0; cnt = 0;
if(!n && !m) { break; }
memset(flag, 0, sizeof flag);
for(int i = 1; i <= m; ++i) {
tmp = 0; ops = -1;
for(int i = 1; i <= n; ++i) { ch = get(); if(ch == '*') { ops = n - i; } tmp = (tmp << 1) + ((ch == '*' || ch == '0') ? 0 : 1) ; }
if(ops != -1) { flag[tmp] = 1; flag[tmp | (1 << ops)] = 1; }
else { flag[tmp] = 1; }
}
num = 0;
memset(cou, 0, sizeof cou);
for(int i = 0, j; i < 1 << n; ++i) { if(flag[i]) { poi[++num] = j = i ; while(j > 0) { cou[num] += (j & 1); j = j / 2; } } }
/* 建边 1是奇数向 1是偶数的 */
memset(h, -1, sizeof h);
for(int i = 1; i <= num; ++i) {
if(! (cou[i] & 1)) { continue; }
for(int j = 1; j <= num; ++j) { if(! (cou[j] & 1) && ok(i, j)){ edge[cnt].insert(i, j); } }
}
memset(p, 0, sizeof p);
for(int i = 1; i <= num; ++i)
{ if(!(cou[i] & 1)) { continue; } memset(flag, 0, sizeof flag); if(find(i)) { ans++; } }
write(num - ans); putchar('
');
}
return 0;
}
以上是关于poj2724的主要内容,如果未能解决你的问题,请参考以下文章