传送门


真是菜死了模板题都不会……

首先\(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 打扫房间 二分图、网络流的更多相关文章

  1. 洛谷$P3877\ [TJOI2010]$打扫房间 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 昂考虑把题目的约束条件详细化?就说每个格点能向四连通连边,问能否做到每个格点度数等于2? $umm$就先黑白染色建两排点呗,然后就$S$向左侧连流量为2的边 ...

  2. [TJOI2010]打扫房间

    题目描述 学校新建了一批宿舍,值日生小A要把所有的空房间都打扫一遍.这些宿舍的布局很奇怪,整个建筑物里所有的房间组成一个N * M的矩阵,每个房间的东南西北四面墙上都有一个门通向隔壁房间.另外有些房间 ...

  3. 洛谷P3877 [TJOI2010]打扫房间 解题报告

    首先整理一下条件: 1.恰好进出每个需打扫的房间各一次 2.进出每个房间不能通过同一个门 (其实前两个条件是一回事) 3.要求每条路线都是一个闭合的环线 4.每条路线经过的房间数大于2 让你在一个n* ...

  4. P3877 [TJOI2010]打扫房间

    xswl以为是个插头dp,然后发现就是个sb题 相当于就是个匹配.每个格子度数为2,所以可以匹配2个相邻的点.匹配显然的用网络流.最后check有没有不匹配的点即可. #include<bits ...

  5. 二分图&网络流&最小割等问题的总结

    二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...

  6. hdu1569-方格取数-二分图网络流

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  7. 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】

    P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...

  8. 「SDFZ听课笔记」二分图&&网络流

    二分图? 不存在奇环(长度为奇数的环)的图 节点能黑白染色,使得不存在同色图相连的图 这两个定义是等价哒. 直观而言,就是这样的图: 二分图有一些神奇的性质,让一些在一般图上复杂度飞天的问题可以在正常 ...

  9. 洛谷 P2756 飞行员配对方案问题 (二分图/网络流,最佳匹配方案)

    P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...

随机推荐

  1. NO.1食品超市经营管理的数据方案

    背景 丸悦是一家日资企业,经营管理方式有着很强的日本文化风格:讲流程.重细节.丸悦2013年进入中国,沿袭固有经营管理方式,并且只选择日本供应商合作,日常经营出现诸多摩擦,最终多方原因导致年亏损300 ...

  2. JQuery实战中遇到的两个小问题$(document).ready() 、bind函数的参数传递问题

    一.$(document).ready() 与 window.onload的区别 1.执行时间 window.onload 必须等到页面内所有元素(包括图片 css js等)加载完毕后才会执行. $( ...

  3. C#语言————格式化数值结果表

    字符 说明                                     示例                                                 输出结果.C ...

  4. 第五章 绘图基础(ALTWIND)

    线上箭头表示画线的方向.WINDING模式和ALTERNATE模式都会填充三个封闭的L型区域,号码从1到3.两个更小的内部区域,号码为4和5,在ALTERNATE模式下不被填充.但是在WINDING模 ...

  5. Linux 小知识翻译 - 「Linux」和病毒

    据说,「Linux」系统上的病毒要远远少于Windows系统上病毒.从2种系统的普及度来看,这是很显然的, 「Linux」的使用人群很少,所以「Linux」上的病毒的扩散时,受害的范围也不大. 但是, ...

  6. python基础 - 字符串作

    split(sep=None, maxsplip=-1) 从左到右 sep 指定分隔字符串,缺省情况下空白字符串,指定的字符串会被切掉 maxsplit 指定分隔次数,-1 表示遍历 rsplit(s ...

  7. Java设计模式之五 ----- 外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  8. Java-栈的学习(字符串的反转)

    StackX类 public class StackX{ private int maxSize; private char StackArray[]; private int top; public ...

  9. 控件布局_TableLayout

    <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android=" ...

  10. 23个Python爬虫开源项目代码

    今天为大家整理了23个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快 1.WechatSogou [1]– 微信公众号 ...