给你一个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. fatal: Paths with -a does not make sense.

    git commit -am '*屏蔽设置缓存' htdocs/s.php fatal: Paths with -a does not make sense. 应该用下面的这样. git commit ...

  2. systemd

    本文参照:https://wiki.archlinux.org/index.php/Systemd#Basic_systemctl_usage 做了翻译和整理 systemd是Linux下的一种ini ...

  3. vue-cli + webpack 多页面实例应用

    关于vue.js vue.js是一套构建用户界面的 轻型的渐进式前端框架.它的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.使用vue可以给你的开发带来极致的编程体验. 关于vu ...

  4. POJ 1850 Code

    组合数学.... Code Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7202 Accepted: 3361 Descrip ...

  5. uva.10020 Minimal coverage(贪心)

    10020 Given several segments of line (int the X axis) with coordinates [Li, Ri]. You are to choose t ...

  6. cf.301.D. Bad Luck Island(dp + probabilities)

    D. Bad Luck Island time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. C#利用Web Service实现短信发送(转)

    通过编程方式实现短信息的发送对很多人来说是一件比较烦杂的事情,目前一般的解决方法是通过计算机和手机的连线,通过可对手机编程的语言编写相关的手机短信息程序来实现,而这种方法对于一般人来说是很难达到的,因 ...

  8. Python-Matplotlib安装及简单使用

    在使用NumPy进行学习统计计算时是枯燥的,大量的数据令我们很头疼,所以我们需要把它图形化显示. Matplotlib是一个Python的图形框架,类似于MATLAB和R语言. Matplotlib的 ...

  9. JS的构造函数

    //构造函数  //使自己的对象多次复制,同时实例根据设置的访问等级可以访问其内部的属性和方法  //当对象被实例化后,构造函数会立即执行它所包含的任何代码  function myObject(ms ...

  10. JAVA设计模式 之 策略模式

    一. 定义 设计模式定义了算法族,分别封装起来,让他们之间可以互相替代,此模式让算法的变化独立于使用算法的客户(该定义来自于Head First 设计模式). 二. 应用场景 当我们在应用程序中完成一 ...