给你一个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(二分图匹配)的更多相关文章

  1. UVALive 5903 Piece it together 二分匹配,拆点 难度:1

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  2. UVALive 5903 Piece it together

    一开始用的STL一直超时不能过,后来发现AC的代码基本都用的普通邻接表,然后改了一下13s,T=T,效率太低了.然后把某大神,详情戳链接http://acm.hust.edu.cn/vjudge/pr ...

  3. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  4. Tracer Deployment UVALive - 8271 二分图匹配

    复习二分图又想起了这道题,裸的二分图匹配,直接匈牙利算法就可以了,mark一下这个比较好用的稠密图匈牙利算法模板 题目:题目链接 AC代码: #include <iostream> #in ...

  5. 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 ...

  6. hdu_1045Fire Net(二分图匹配)

    hdu_1045Fire Net(二分图匹配) 标签: 图论 二分图匹配 题目链接 Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...

  7. 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 ...

  8. HDU1045:Fire Net(二分图匹配 / DFS)

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  9. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

随机推荐

  1. 时间处理工具类DateUtils

    public class DateUtils {         public static final String                            SHORT_DATE    ...

  2. [设计模式] javascript 之 模板方法模式

    模板方法模式说明 定义:定义方法操作的骨架,把一些具体实现延伸到子类中去,使用得具体实现不会影响到骨架的行为步骤! 说明:模式方法模式是一个继承跟复用的典型模式,该模式定义了一个抽象类,Abstrac ...

  3. 密码学初级教程(六)数字签名 Digital Signature

    密码学家工具箱中的6个重要的工具: 对称密码 公钥密码 单向散列函数 消息认证码 数字签名 伪随机数生成器 提问: 有了消息认证码为什么还要有数字签名? 因为消息认证码无法防止否认.消息认证码可以识别 ...

  4. Android中实现圆角矩形及半透明效果。

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在做Android开发时,我们为了美观,有时候需要使用圆角矩形,或半透明之类的效果,在网页设计中很容易实现.但在Android开发中 ...

  5. iOS 滑动性能优化

    iOS 滑动性能优化 目录 一. 减少图层的Blend操作 1. UIView的背景色避免使用clearColor 2. 控件贴图避免使用带alpha的图片 3. UIImageView 使用时避免半 ...

  6. 自动去除nil的NSDictionary和NSArray构造方法

    http://www.jianshu.com/p/a1e8d8d579c7 极分享 http://www.finalshares.com/

  7. CAN总线 SJA1000中断

    背景: 最近一直在使用C8051F340 + SJA1000来实现CAN通信,就SJA1000部分做个记录. 正文: 整个系统结构拓扑图如下: 两路CAN,C8051F340作为CPU,处理CAN与U ...

  8. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  9. 63.Hbase 常用命令

    1.进入 Hbase shell ./hbase shell 2. 命令 1.list 2.truncate 3.scan 4.describe 5.create 'tablename','famil ...

  10. 淘宝(阿里百川)手机客户端开发日记第十三篇 mysql的连接

    首先,我建立了一个包,里面存放了三个类文件,这三个文件是我从网络中找的,经过自己的整理.(我刚才查找想把这三个文件传上去,可能是自己对cnblogs的博客不太熟悉吧,没有找到,我只好粘贴代码了) 三个 ...