首先整理一下条件:

1、恰好进出每个需打扫的房间各一次

2、进出每个房间不能通过同一个门

(其实前两个条件是一回事)

3、要求每条路线都是一个闭合的环线

4、每条路线经过的房间数大于2

让你在一个n*m的矩阵中,找出是否能按照约定方案打扫全部指定房间。

首先不难得出一个结论:有奇数个需要打扫的房间时一定无解。

证明?

每一次打扫都要满足条件3和4,而闭合的环线为多边形,显然必须对称(即通过平移可得到矩形),不难看出:每一次都能且只能打扫偶数个房间。

然后稍作分析,发现每个格子的度为2(即进入此房再出去)。

考虑建图。

一个房间上下左右有门,我们自然而然想到一个点向周围四个连边,就构成了黑白染色的模型。

一个矩阵中的房间最多用两条路线打扫即可。

每个点都要走到。

所以每个点都会向上下左右异色格点流出1,同时也会接受另一个点的流入。

我们这时将白点流向黑点的流反向,这样每个白点流入2,每个黑点流出2。

于是每个点有2的流量,来说明可以有两条边和它相连。

黑点都向S连边,白点都向T连边

然后图建好了,开始跑网络流,如果满流就证明所有的点都进,出过一次,打扫完毕,输出yes;否则no

建图总结:

  • 节点含义:房间
  • 边的含义:打扫路线
  • 边如何相连:四连通
  • 源点S:矩阵外一点
  • 汇点T:矩阵外一点

代码:


#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define inf 0x7fffffff
int n,m,s,t,ans;
int gx[5]={0,0,-1,0,1};
int gy[5]={0,-1,0,1,0};
//int gy[5]={0,-1,1,0,0};
//int gx[5]={0,0,0,-1,1};
int d[1000],id[105][105];
char a[105][105];
struct edge
{
int to,val,rev;
edge(int _to,int _val,int _rev)
{
to=_to;
val=_val;
rev=_rev;
}
};
vector<edge>e[1000];
void add(int x,int y,int w)
{
e[x].push_back(edge(y,w,e[y].size()));
e[y].push_back(edge(x,0,e[x].size()-1));
}
bool bfs()
{
memset(d,-1,sizeof(d)); queue<int>q; q.push(s);
d[s]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<e[x].size();i++)
{
int y=e[x][i].to;
if((d[y]==-1)&&e[x][i].val)
{
q.push(y);
d[y]=d[x]+1; }
}
}
if(d[t]==-1)
return 0;
else
return 1;
}
int dfs(int x,int low)
{
if(x==t||low==0)return low;
int totflow=0;
for(int i=0;i<e[x].size();i++)
{
int y=e[x][i].to;
int rev=e[x][i].rev;
if((d[y]==(d[x]+1))&&e[x][i].val)
{
int a=dfs(y,min(low,e[x][i].val));
e[x][i].val-=a;
e[y][rev].val+=a;
low-=a;
totflow+=a;
if(low==0)return totflow;
}
}
if(low!=0)d[x]=-1;
return totflow;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<=1000;i++)
e[i].clear();
int cnt=0,tot=0,sum=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
id[i][j]=++cnt;
if(a[i][j]=='.')tot++;
}
}
s=0;
t=cnt+1;
if(tot%2==1)
{
printf("NO\n");
continue;
}
if((n==1)||(m==1))
{
printf("NO\n");
continue;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='.')
{
if(((i+j)%2)==1)
{
add(s,id[i][j],2);
sum+=2;
for(int k=1;k<=4;k++)
{
int nx=i+gx[k];
int ny=j+gy[k];
if((nx>=1)&&(nx<=n)&&(ny>=1)&&(ny<=m)&&(a[nx][ny]!='#'))
add(id[i][j],id[nx][ny],1);
}
}
else
{
add(id[i][j],t,2);
}
}
}
}
ans=0;
while(bfs())
{ ans+=dfs(s,inf);
}
if(ans==tot)
{
printf("YES\n");
}
else
printf("NO\n");
}
return 0;
}

洛谷P3877 [TJOI2010]打扫房间 解题报告的更多相关文章

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

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

  2. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  3. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  4. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  5. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  6. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  7. 洛谷 P1457 城堡 The Castle 解题报告

    P1457 城堡 The Castle 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张"幸运爱尔兰" ...

  8. 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告

    [USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...

  9. 洛谷 P1502 窗口的星星 解题报告

    P1502 窗口的星星 题目背景 小卡买到了一套新房子,他十分的高兴,在房间里转来转去. 题目描述 晚上,小卡从阳台望出去,"哇~~~~好多星星啊",但他还没给其他房间设一个窗户, ...

随机推荐

  1. ORACLE 11.2.0.4 安装在 rhel6 上

    . 修改host文件,添加本机的host记录 [root@RACDG ~]# vi /etc/hosts 127.0.0.1 localhost localhost.localdomain local ...

  2. Python:Pandas学习

    import pandas as pd import numpy as np s = pd.Series([1, 3, 6, np.nan, 44, 1]) df= pd.DataFrame(np.r ...

  3. Ptypes一个开源轻量级的c++库,包括对一些I/O操作、网络通信、多线程和异常处理的封装

    C++开源项目入门级:Ptypes    Ptypes一个开源轻量级的c++库,包括对一些I/O操作.网络通信.多线程和异常处理的封装.虽然代码有限,包括的内容不少,麻雀虽小,五脏俱全.    提高: ...

  4. T4生成整理

    将一些公用的东西弄到一个类库DM.T4里面,哪个项目需要用到t4生成的话,将DM.T4的生成事件中将dll和ModelAuto.ttinclude复制到需要使用T4的项目的生成目录下,如果这样 cop ...

  5. [每天记录一个Bug]Cell中由于block加载网络请求产生的复用

    Bug 出现场景:   cell中使用加载图片的网络请求出现复用,截图如下:         复用原因:   Cell Model中只有一个用户的uid,所有用户相关信息:例如头像\名称\信息等是通过 ...

  6. 【canvas】基础练习一 图形

    Demo1[绘制一条线] <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  7. django自带的cache

    cache语法 from django.core.cache import cache #存入内存 cache.set("aaa",123) #从内存中获取 cache.get(& ...

  8. python爬虫之PyQuery

    # -*- coding: UTF-8 -*- from pyquery import PyQuery as pq import re from datetime import datetime,ti ...

  9. Python连载15-高阶函数&map映射

    一.高阶函数 1.定义:把函数作为参数使用的函数叫做高阶函数 (1)变量可以设置为赋值 a=100 b=a (2)函数名称就是一个变量 def FunA(): print("FunA()&q ...

  10. 向HashMap中添加1000个元素,设置new HashMap()值为多少合适?

    在已知元素容量的情况下,为了尽量减少碰撞增加查询效率,应该尽量选择较大数的同时避免资源浪费. HashMap底层通过hash值来计算索引位置的源码: 1.重新计算hash值 static final ...