传送门


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

首先\(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. 【读书笔记】iOS-iOS安全基础知识

    一,iOS硬件/设备的类型. iPad的问世,就是在这一方向上迈出的第一步.第一代iPad使用了ARM Cortex-A8架构的CUP,它的速度大约是第一代iPhone所使用CPU速度的两倍. iPa ...

  2. Centos 6.8 系统升级默认的Python版本

    1.编译安装python2.7 # wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz # Python-2.7.12.tg ...

  3. css文本属性用法总结

    稍稍总结了下css文本的一些属性用法,自己忘记的时候也可以用来查查,不用去查网站那么麻烦. 下面是部分总结,也希望对其他人有用 文本修饰 (1)text-decoration:  文本修饰(横线) 4 ...

  4. mysql的varchar字段可以存储多少个中文字符

    创建数据库,并创建一张表mytb进行测试 ******************************************************************************* ...

  5. 洗礼灵魂,修炼python(12)--python关键词,包

    关键词 1.什么是关键词: 就是系统已经定义好的一些关键词语法,可以直接使用,很明显的就是在IDE里这些关键词会高亮显示的就是 2.有哪些关键词: 前面我们一直在说关键词,内置函数,到底有哪些关键词对 ...

  6. JDK动态代理源码解析

    动态代理.静态代理优缺点     关于JDK的动态代理,最为人熟知的可能要数Spring AOP的实现,默认情况下,Spring AOP的实现对于接口来说就是使用的JDK的动态代理来实现的,而对于类的 ...

  7. SQL Server2008 18456错误

    1.以windows验证模式进入数据库管理器.   第二步:右击sa,选择属性:   在常规选项卡中,重新填写密码和确认密码(改成个好记的).把强制实施密码策略去掉.   第三步:点击状态选项卡:勾选 ...

  8. VS code 修改主题设置代码对其齐线

    用VS Code 写代码的时候有时候缩进太多就不知道对应的是哪一个标签了,那么可不可以让它显示缩进参考线,这样就清楚的多了.答案是肯定的,方法如下: 找到 文件-->首选项——>设置→搜索 ...

  9. v-bind指令动态绑定class和内联样式style

    动态绑定class—概述 数据绑定(v-bind指令)一个常见需求是操作元素的 class 列表.因为class是元素的一个属性,我们可以用 v-bind 处理它们 我们只需要计算出表达式最终的字符串 ...

  10. Python数据分析实例操作

    import pandas as pd #导入pandas import matplotlib.pyplot as plt #导入matplotlib from pylab import * mpl. ...