HDU5556 Land of Farms(二分图 2015 合肥区域赛)
容易想到将问题转化为求图的独立数问题 ,但求一般图的独立集是一个NPC问题,需要一些转化。
状态压缩,枚举每个上古农场是否选择,然后将剩下的新农场根据i + j奇偶性分为x , y集。
结果为 max(tot + nx + ny - 二分图匹配数)
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 150, INF = 0x3F3F3F3F; int mp[15][15]; int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int cx[N], cy[N];//匹配结果
int nx, ny;//x,y集合元素个数
bool inx[N], iny[N]; bool used[N];
bool nop[15][15]; //存x到y集合的有向图
struct Node{
int to,next;
}edge[1000];
int head[N],tot; bool dfs(int u){
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(!used[v]){
used[v] = true;
if(cy[v] == -1 || dfs(cy[v])){
cx[u] = v;
cy[v] = u;
return true;
}
}
}
return false;
} int Hungary(){
int ans = 0;
memset(cx, -1, sizeof(cx));
memset(cy, -1, sizeof(cy));
for(int i = 0; i < nx; i++){
if(cx[i] == -1){
memset(used, 0, sizeof(used));
if(dfs(i)){
ans++;
}
}
}
return ans;
} void init(){
memset(head, -1, sizeof(head));
tot = 0;
}
void add(int u, int to){
edge[tot].to=to;
edge[tot].next=head[u];
head[u]=tot++;
} bool check(int n, int m, int st){
memset(nop, 0, sizeof(nop));
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(st & (1 << mp[i][j])){
for(int k = 0; k < 4; k++){
int u = i + dir[k][0];
int v = j + dir[k][1];
if((mp[u][v] != -1) && (mp[i][j] != mp[u][v]) && (st & (1 << mp[u][v]))){
return false;
}
nop[u][v] = 1;
}
}
}
}
return true; }
char str[N];
int main(){
int t, n, m;
cin>>t;
int vis[N];
for(int cas = 1; cas <= t; cas++){
scanf("%d %d", &n, &m);
int ans = 0;
memset(mp, -1, sizeof(mp));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++){
scanf("%s", str + 1);
for(int j = 1; j <= m; j++){
if(str[j] == '.'){
mp[i][j] = 10;
}else{
mp[i][j] = str[j] - '0';
vis[str[j] - '0'] = 1;
}
}
}
int cnt = 0;
for(int i = 0; i < 10; i++){
if(vis[i]){
vis[i] = cnt++;
}
} for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(mp[i][j] < 10){
mp[i][j] = vis[mp[i][j]];
}
}
} for(int st = 0; st < (1 << cnt); st++){
int tot = 0;
int tp = st;
while(tp){
tot += tp & 1;
tp >>= 1;
} if(!check(n, m, st)){
continue;
}
init();
nx = 0;
ny = 0;
memset(inx, 0, sizeof(inx));
memset(iny, 0, sizeof(iny));
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(mp[i][j] < 10){
nop[i][j] = 1;
} if((i + j) % 2){
if(mp[i][j] == 10 && !nop[i][j]){
iny[(i - 1) *m + j - 1] = 1;
}
} if((i + j) % 2 == 0){
if(mp[i][j] == 10 && !nop[i][j]){
inx[(i - 1) *m + j - 1] = 1;
for(int k = 0; k < 4; k++){
int u = i + dir[k][0];
int v = j + dir[k][1];
if(mp[u][v] == 10 && !nop[u][v]){
add((i - 1) *m + j - 1, (u - 1) *m + v - 1);
} } } } }
}
for(int i = 0; i < n * m; i++){
if(inx[i]){
tot++;
nx = i + 1;
}
if(iny[i]){
tot++;
ny = i + 1;
}
}
ans = max(ans, tot - Hungary());
} printf("Case #%d: %d\n", cas, ans);
} return 0;
}
HDU5556 Land of Farms(二分图 2015 合肥区域赛)的更多相关文章
- HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)
当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...
- hdu5556 Land of Farms
我对于题目的一种理解 改造农场 1.建新农场 在空的点选 2.重建旧农场 选一个点属于这个农场的地方都要选 最后的农场都不能相连 所以枚举旧农场的个数并进行二分图匹配 #include<bits ...
- 2015北京区域赛 Xiongnu's Land
Wei Qing (died 106 BC) was a military general of the Western Han dynasty whose campaigns against the ...
- Travel(HDU 5441 2015长春区域赛 带权并查集)
Travel Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Su ...
- hdu 5493 (2015合肥网赛) Queue
题目;http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意,t组数据,n个人,n行每行分别是人的身高和这个人的左边或右边比他高的人的个数,输出符合条件 ...
- hdu 5491(2015合肥网赛)The Next
题目;http://acm.hdu.edu.cn/showproblem.php?pid=5491 题意就是,T组测试数据.然后L,S1,S2.L的二进制中有x个1,x满足 S1<=x< ...
- HDU 5552 Bus Routes(2015合肥现场赛A,计数,分治NTT)
题意 给定n个点,任意两点之间可以不连边也可以连边.如果连边的话可以染上m种颜色. 求最后形成的图,是一个带环连通图的方案数. 首先答案是n个点的图减去n个点能形成的树. n个点能形成的树的方案数比 ...
- ACM学习历程—HDU5490 Simple Matrix (数学 && 逆元 && 快速幂) (2015合肥网赛07)
Problem Description As we know, sequence in the form of an=a1+(n−1)d is called arithmetic progressio ...
- 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)
HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...
随机推荐
- PHP环境搭建——Apache、Mysql、PHP单独安装(for Windows)
提示: 安装之前先要安装vcredist_x86.exe或vcredist_x64.exe(vc6,vc9,vc11等,和下面对应). 确保apache和php是用同样版本的编译器编译出来的,如果是v ...
- VQuery高级特性
VQuery高级特性 css方法 同时设置多个--for in 链式操作 链式操作 函数,链式操作 css 方法链式操作 json的使用 阻止冒泡,默认事件 VQuery插件 插件机制 可以扩展库的功 ...
- HTK学习1:安装编译
选自:http://www.cnblogs.com/mingzhao810/archive/2012/08/03/2617674.html HTK(HMM Toolkit)一款基于hmm模型的语音处理 ...
- Js 的 this 是什么
this指的是调用函数的那个对象,谁调用函数,谁就是this 更多: http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_thi ...
- phalcon 前端代码结构
phalcon 前端举例: (1) baisic.phtml + basic_ajax_get.phtml + basic_ajax_post.phtml (2) basic_get.phtml ...
- 一个Try多个Catch需要注意的事项
一个程序包含一个try块和两个catch块,两个catch子句都有能力捕捉一个try块发出的异常,若两个catch子句次序不同时程序结果会发生变化吗? 一个try块后有两个catch块,这很正常,因为 ...
- hdu3652
基本的数位dp,需要记录前面除以13的余数. #include <cstdio> #include <cstring> using namespace std; #define ...
- cxGrid 速度
在做AdoHelper实用程序的时候,我用了DevExpress的cxGrid控件.在此之前用的是dbgrid,考虑到不能把所有的数据都拉到本地,我用了动态生成的select top 500的命令.这 ...
- ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))
两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...
- 最简单粗暴的http文件列表
:]: port = ])else: port = 8000server_address = ('127.0.0.1', port)Handler.protocol_version = Protoco ...