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) ...
随机推荐
- CF456B Fedya and Maths 找规律
http://codeforces.com/contest/456/problem/B CF#260 div2 B Fedya and Maths Codeforces Round #260 B. F ...
- IIS 您要访问的网页有问题,无法显示!
提示:您要访问的网页有问题,无法显示.HTTP 500 – 内部服务器错误.”的问题解决方案! IIS服务器出现错误的原因很多,请尝试以下操作:1.查看网站属性——文档看看启用默认文档中是否存在:in ...
- iOS9 Universal Link实现
先来贴几个比较全面的帖子,看完就差不多了. 1 iOS 9 通用链接(Universal Links) 帖子注意项非常重要,仔细阅读. 自己补充几点: 1 服务器上配置的json文件apple-a ...
- PHP基础之 错误处理 及 异常处理
错误处理: 1.使用die()方法,结束语句的执行,并输出错误消息 2.自定义错误和错误触发器 自定义错误处理函数(系统有默认的错误处理函数,自定义的错误处理会覆盖默认的处理函数) ========= ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- 用SQLite查看编辑android导出的微信聊天记录
上一篇我们已经能够完成文字版微信聊天记录导出android了,也即复制或剪切MicroMsg.db文件到电脑,以.db格式结尾的文件是数据库文件(database document),需要安装相关数据 ...
- LUXURY15
A - Guess Your Way Out! Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- Unity手游之路<三> 基于Unity+Java的聊天室源码
http://blog.csdn.net/janeky/article/details/17233199 项目介绍 这是一个简单的Unity项目,实现最基本的聊天室群聊功能.登录聊天室后,用户可以输入 ...
- Unity手游之路<十一>资源打包Assetbundle
http://blog.csdn.net/janeky/article/details/17652021 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制 ...
- [KOJ6024]合并果子·改(强化版)
[COJ6024]合并果子·改(强化版) 试题描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多把这些果子堆排成一排,然后所有的果子合成一堆. 每一次合并 ...