UVALive 5903 Piece it together(二分图匹配)
给你一个n*m的矩阵,每个点为'B'或'W'或'.'。然后你有一种碎片。碎片可以旋转,问可否用这种碎片精确覆盖矩阵。N,M<=500
WB 《==碎片
W
题目一看,感觉是精确覆盖(最近被覆盖洗脑了),但是仔细分析可以知道,DLX精确覆盖不是正解。因为N*M=250,000远超出DLX的可行规模(数百吧,我猜)。
然后感觉是贪心或者是抑或的什么的。。。。
看了别人的代码,发现是最大匹配。。。然后就想。。。。对哦=。=其实黑点连2个白点就是匹配呀。。。。
不得不说网络流构图还是挺有趣的,如果你会构的话。。。。
首先,如果NB*2!=NW,那必然是NO,此处特判。
构图是这样,每个黑点拆分成2个,一个只连接左右邻接的白点,一个只连接上下邻接的白点。然后就匹配了=。=
规模分析:250,000/3*2=166,666个黑点(黑点拆分翻倍),250,000/3*2=166,666个白点。边有166,666*2=333,332条。。
一开始写完这题是TLE...然后改了5处从>30sec变成100ms,还是有点收获的。。。
①如果某一个黑点匹配的那个match返回0而不是1,说明有黑点没匹配到,可直接break;结果为NO。。。。>30sec ==> 27sec,TLE==>AC
②将maxn的500,000改成180,000,快了不少。。几秒吧。。。原因应该是多case的mesmet head
③将2个for找B字符改成统计时存B字符位置。。也快了些。
④将加边的顺序改成先加左(上)边的边,再加右(下)边的边。。这个从17sec变成了3sec。。。
⑤将二分匹配的vis改成int,避免多次memset。。这个从3sec变成了100ms。。。
第一点显然的剪枝,不说了。二三点好像快得也不是特别明显,不说了。
第四点,假设某行某段是WBW,那先加左边,再加右边的结果是B->W2->W1,也就是优先右边。。。这样的话,
如果某行某段是 BWBWBWBWBWBW,那匹配的时候,每个B都只需要匹配一个就成功,不需要回溯。。。。这个的前提是顺序匹配,即从1~2B
反之,如果先加右边,再加左边的结果是B->W1->W2,也就是优先左边。。。那样的话就要回溯多次(因为还有列的影响)。。但如果是逆序匹配,即从2B~1,速度还是几秒
第五点。。。应该是最有力的改进了。。。。传统的二分匹配的vis是bool,然后匹配前memset。。因为那些点一般是数百。。。
但是我们可以把vis改成int,匹配的时候把if(vis[v])continue;改成if(vis[v]==ID)continue;
二分图最大匹配当时学得不够深入啊╮(╯▽╰)╭。。。。今天学习了。。。。第四点是SF发现的。。。第五点是参考LC他们的。。。感谢SF陪我刷了一两页的AC...
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <set>
using namespace std; #define ll long long
#define inf 0x3f3f3f3f
#define eps 1e-8
#define maxn 180000
#define maxm 360000 int vv[maxm],nxt[maxm];
int head[maxn],E;
void init(){memset(head,-,sizeof(head));E=;}
void addedge(int u,int v){
vv[E]=v,nxt[E]=head[u],head[u]=E++;
}
int pre[maxn];
int vis[maxn];
bool match(int x,int n,int ID){
for(int i=head[x];i!=-;i=nxt[i]){
int v = vv[i]-n;
if(vis[v]==ID)continue;
vis[v] = ID;
if(pre[v]==- || match(pre[v],n,ID)){
pre[v]=x;
return true;
}
}
return false;
}
bool hungary(int n){
memset(pre,-,sizeof(pre));
memset(vis,,sizeof(vis));
for(int i=;i<=n;++i)
if(match(i,n,i)==false)return false;
return true;
} char ch[][];
int idx[][];
int bx[maxn],by[maxn];
int main(){
int t;
scanf("%d",&t);
while(t--){
int nn,mm;
scanf("%d%d",&nn,&mm);
memset(ch,,sizeof(ch));
for(int i=;i<=nn;++i)scanf("%s",ch[i]+);
int B=,W=;
for(int i=;i<=nn;++i)for(int j=;j<=mm;++j)
if(ch[i][j]=='B')idx[i][j]=++B,bx[B]=i,by[B]=j;
else if(ch[i][j]=='W')idx[i][j]=++W;
if(B*!=W){puts("NO");continue;}
init();
for(int b=;b<=B;++b){
int i=bx[b],j=by[b];
if(ch[i-][j]=='W')addedge(idx[i][j],B*+idx[i-][j]);
if(ch[i+][j]=='W')addedge(idx[i][j],B*+idx[i+][j]);
if(ch[i][j-]=='W')addedge(idx[i][j]+B,B*+idx[i][j-]);
if(ch[i][j+]=='W')addedge(idx[i][j]+B,B*+idx[i][j+]);
}
if(hungary(B<<))puts("YES");
else puts("NO");
}
return ;
}
UVALive 5903 Piece it together(二分图匹配)的更多相关文章
- UVALive 5903 Piece it together 二分匹配,拆点 难度:1
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- UVALive 5903 Piece it together
一开始用的STL一直超时不能过,后来发现AC的代码基本都用的普通邻接表,然后改了一下13s,T=T,效率太低了.然后把某大神,详情戳链接http://acm.hust.edu.cn/vjudge/pr ...
- 训练指南 UVALive - 4043(二分图匹配 + KM算法)
layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...
- Tracer Deployment UVALive - 8271 二分图匹配
复习二分图又想起了这道题,裸的二分图匹配,直接匈牙利算法就可以了,mark一下这个比较好用的稠密图匈牙利算法模板 题目:题目链接 AC代码: #include <iostream> #in ...
- HDU 1507 Uncle Tom's Inherited Land*(二分图匹配)
Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- hdu_1045Fire Net(二分图匹配)
hdu_1045Fire Net(二分图匹配) 标签: 图论 二分图匹配 题目链接 Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- HDU1045 Fire Net(DFS枚举||二分图匹配) 2016-07-24 13:23 99人阅读 评论(0) 收藏
Fire Net Problem Description Suppose that we have a square city with straight streets. A map of a ci ...
- HDU1045:Fire Net(二分图匹配 / DFS)
Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- HDU 1045 Fire Net 【连通块的压缩 二分图匹配】
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
随机推荐
- PHP+MySQL存储数据出现中文乱码的问题
PHP+MySQL出现中文乱码的原因: 1. MYSQL数据库的编码是utf8,与PHP网页的编码格式不一致,就会造成MYSQL中的中文乱码. 2. 使用MYSQL中创建表.或者选择字段时设置的类型不 ...
- jQuery.Callbacks 源码解读二
一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...
- Jquery网页加载进度条(随笔,当然要随便写,当日记动态心情写咯)
首先先是吐槽时间... 告诉大家一个好消息,就是有个妹子非常仰慕我的前端技术说要包养我 然后有好多羡慕嫉妒恨的童鞋一定要说,少年你太天真了,那一定是HR 然后我表示她不是HR,本宅的春天貌似要到来了. ...
- HDOJ 2929 Bigger is Better
DP....好难的DP... Bigger is Better Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 ...
- 【bzoj1864】[ZJOI2006]三色二叉树
题目描述 输入 仅有一行,不超过500000个字符,表示一个二叉树序列. 输出 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. 样例输入 1122002010 样例输出 ...
- cocos2d-x多分辨率适配方案:setDesignResolutionSize使用
1. setDesignResolutionSize使用方法及主要的三种适配模式 在cocos2d-x 2.0里,提供了一个叫做setDesignResolutionSize的方法,直接一次设置就可以 ...
- (:: operator)作用域限定符的几种使用
一.(:: operator)解决局部变量与全局变量重名问题 ; int main() { ; cout<<var<<endl;//local variable cout< ...
- Swift2.1 语法指南——类型转换
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
- C++之通用队列模版
功能:在qtcreator上用模版的方式实现队列数据格式存储多样化. 模版实现的两种方式: 1.模版的实现直接在头文件里声明并定义,别的类通过#include"*.h"进行包含,则 ...
- OpenCV图像Canny边缘检测
Canny边缘检测 图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘函数原型: void cvCanny( ...