Luogu3877 TJOI2010 打扫房间 二分图、网络流
真是菜死了模板题都不会……
首先\(30 \times 30\)并不能插头DP,但是范围仍然很小所以考虑网络流。
注意每个点都要包含在一个回路中,那么每一个点的度数都必须为\(2\),也就是说每一个点必须向与它四连通的点中恰好\(2\)个连边。而“四连通”又是经典的黑白染色+二分图模型。
所以对于原图黑白染色,原点向黑点、白点向汇点连流量为\(2\)的边,相邻的黑点向白点连流量为\(1\)的边,跑一边Dinic看最大流等于需要打扫的格点数量。
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 1e5 + 7 , MAXM = 1e6 + 7;
struct Edge{
int end , upEd , f , c;
}Ed[MAXM];
int head[MAXN];
int N , M , S , T , cntEd = 1;
queue < int > q;
inline void addEd(int a , int b , int c , int d = 0){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].f = c;
Ed[cntEd].c = d;
head[a] = cntEd;
}
int cur[MAXN] , dep[MAXN];
inline bool bfs(){
while(!q.empty())
q.pop();
q.push(S);
memset(dep , 0 , sizeof(dep));
dep[S] = 1;
while(!q.empty()){
int t = q.front();
q.pop();
for(int i = head[t] ; i ; i = Ed[i].upEd)
if(Ed[i].f && !dep[Ed[i].end]){
dep[Ed[i].end] = dep[t] + 1;
if(Ed[i].end == T){
memcpy(cur , head , sizeof(head));
return 1;
}
q.push(Ed[i].end);
}
}
return 0;
}
inline int dfs(int x , int mF){
if(x == T)
return mF;
int sum = 0;
for(int &i = cur[x] ; i ; i = Ed[i].upEd)
if(Ed[i].f && dep[Ed[i].end] == dep[x] + 1){
int t = dfs(Ed[i].end , min(mF - sum , Ed[i].f));
if(t){
Ed[i].f -= t;
Ed[i ^ 1].f += t;
sum += t;
if(sum == mF)
break;
}
}
return sum;
}
int Dinic(){
int ans = 0;
while(bfs())
ans += dfs(S , INF);
return ans;
}
inline char getc(){
char c = getchar();
while(c == ' ' || c == '\n' || c == '\r')
c = getchar();
return c;
}
#define id(i,j) (((i) - 1) * M + j)
const int dir[4][2] = {0,1,0,-1,1,0,-1,0};
char mmap[32][32];
int main(){
#ifndef ONLINE_JUDGE
freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
for(int t = read() ; t ; --t){
N = read();
M = read();
T = N * M + 1;
memset(head , 0 , sizeof(head));
cntEd = 1;
int cnt = 0;
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 ; j <= M ; ++j){
mmap[i][j] = getc();
if(mmap[i][j] == '.'){
++cnt;
if((i + j) & 1){
addEd(S , id(i , j) , 2);
addEd(id(i , j) , S , 0);
}
else{
addEd(id(i , j) , T , 2);
addEd(T , id(i , j) , 0);
}
}
}
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 + (i & 1) ; j <= M ; j += 2){
if(mmap[i][j] == '.')
for(int k = 0 ; k < 4 ; ++k)
if(i + dir[k][0] && i + dir[k][0] <= N)
if(j + dir[k][1] && j + dir[k][1] <= M)
if(mmap[i + dir[k][0]][j + dir[k][1]] == '.'){
addEd(id(i , j) , id(i + dir[k][0] , j + dir[k][1]) , 1);
addEd(id(i + dir[k][0] , j + dir[k][1]) , id(i , j) , 0);
}
}
puts(!(cnt & 1) && Dinic() == cnt ? "YES" : "NO");
}
return 0;
}
Luogu3877 TJOI2010 打扫房间 二分图、网络流的更多相关文章
- 洛谷$P3877\ [TJOI2010]$打扫房间 网络流
正解:网络流 解题报告: 传送门$QwQ$ 昂考虑把题目的约束条件详细化?就说每个格点能向四连通连边,问能否做到每个格点度数等于2? $umm$就先黑白染色建两排点呗,然后就$S$向左侧连流量为2的边 ...
- [TJOI2010]打扫房间
题目描述 学校新建了一批宿舍,值日生小A要把所有的空房间都打扫一遍.这些宿舍的布局很奇怪,整个建筑物里所有的房间组成一个N * M的矩阵,每个房间的东南西北四面墙上都有一个门通向隔壁房间.另外有些房间 ...
- 洛谷P3877 [TJOI2010]打扫房间 解题报告
首先整理一下条件: 1.恰好进出每个需打扫的房间各一次 2.进出每个房间不能通过同一个门 (其实前两个条件是一回事) 3.要求每条路线都是一个闭合的环线 4.每条路线经过的房间数大于2 让你在一个n* ...
- P3877 [TJOI2010]打扫房间
xswl以为是个插头dp,然后发现就是个sb题 相当于就是个匹配.每个格子度数为2,所以可以匹配2个相邻的点.匹配显然的用网络流.最后check有没有不匹配的点即可. #include<bits ...
- 二分图&网络流&最小割等问题的总结
二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...
- hdu1569-方格取数-二分图网络流
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
- 「SDFZ听课笔记」二分图&&网络流
二分图? 不存在奇环(长度为奇数的环)的图 节点能黑白染色,使得不存在同色图相连的图 这两个定义是等价哒. 直观而言,就是这样的图: 二分图有一些神奇的性质,让一些在一般图上复杂度飞天的问题可以在正常 ...
- 洛谷 P2756 飞行员配对方案问题 (二分图/网络流,最佳匹配方案)
P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...
随机推荐
- React自己写的一个地图小组件
由于今天比较闲,就玩了玩react,然后就封装了一个地图的组件,当然功能比较简单,因为就是随手写的小东西,但是由于引用了百度API和bee-mobile,所以用起来可能要薛微麻烦一点点,但是我保证,只 ...
- Salesforce小知识:累计汇总字段类型
累计汇总字段类型的定义 Salesforce中可以在两个对象之间建立关系.一个对象的某一条记录可以有若干条相关联的其他对象记录. 累计汇总字段可以将这些相关联的记录中的某些字段值汇总起来,显示给用户. ...
- 网络基础 cookie详解
cookie详解 by:授客 QQ:1033553122 cookie干嘛用的? 参见文章http 会话(session)详解: 网络基础 http 会话(session)详解 cookie分类 ...
- 配置Synwrite作为Python的IDE
先建立批处理 建立SynPython.bat ::Synwrite call Python to compile file ::Set Path @ set PATH=H:\XPprogram\Cod ...
- 移动端web页面开发常用的头部标签设置
在移动端web页面开发中,我们常需要设置各种头部标签以帮助浏览器更好的解析页面,将页面完美呈现,这里列出了工作中常用的各种头部标签,以备查询. viewport <meta name=" ...
- 针对模拟滚动条插件(jQuery.slimscroll.js)的修改
在开发过程中程序员总会碰到产品经理提出的各种稀奇古怪的需求,尽管有些需求很奇葩,但不得不说有些须有还是能指引我们不断的学习与进步,最近在工作中就碰到这种问题.需求是要求在各主流浏览器上使用自定义的滚动 ...
- Pinyin4j实战
package com.haiyisoft.innovationcenter.pinyin; import org.junit.Test; import net.sourceforge.pinyin4 ...
- 如何将 asp.net core 应用进行 docker 容器部署
asp.net core 部署在 docker 容器中比较简单,但常因asp.net core程序发布的问题造成容器无法正常启动.现在把详细的操作的步骤记录如下: 一.asp.net core web ...
- Head First Android --- Intent
How to create the intentYou create an intent that specifies an action using the following syntax:whe ...
- Cannot uninstall 'pyserial'. It is a distutils installed project and thus we cannot a ccurately determine which files belong to it which would lead to only a partial uninstall. 解决方法
最近再升级 pyserial模块时,采用 pip install --upgrade pyserial,待模块下载完成准备卸载原版本时 提示:“Cannot uninstall 'pyserial'. ...