首先整理一下条件:

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. UWP-消息提示(仿Android)

    原文:UWP-消息提示(仿Android) 在UWP中的消息提示框(一)中介绍了一些常见的需要用户主动去干涉的一些消息提示框,接下来打算聊聊不需要用户主动去干涉的一些消息提示框.效果就是像双击退出的那 ...

  2. SqlServer批量压缩数据库日志-多数据库批量作业,批量备份还原

    原文:SqlServer批量压缩数据库日志-多数据库批量作业,批量备份还原 --作业定时压缩脚本 多库批量操作 DECLARE @DatabaseName NVARCHAR(50) DECLARE @ ...

  3. MySQL操作详解

    创建并使用数据库 查看服务器上的数据库:SHOW DATABASES; 创建数据库:CREATE DATABASE <数据库名>; 指明使用何数据库:USE <数据库名> 创建 ...

  4. Fundamentals Code Library,包含HTTP TCP JSON BigInteger 加密算法 Unicode等许多东西

    http://fundementals.sourceforge.net/index.html https://github.com/fundamentalslib/fundamentals5 http ...

  5. 深入探索ScrollWindow

    最近做WIN32 API开发时发现对ScrollWindow的一些工作原理并不是太清楚,于是做了相关研究,记载下来和大家共同学习. 首先在WM_CREATE中获取系统字符的宽度和高度 case WM_ ...

  6. 写一个可拖动的 TShape(简单有效:依靠VCL体系,TShape自己就能被探测到被点击了,然后只要改变Left坐标就行了)

    问题来源: http://www.cnblogs.com/del/archive/2009/03/09/1234066.html#1471535 本例效果图: 自定义类(TMyShape)单元 : u ...

  7. rest_framework

    一.解析器组件(parser) 1.编程:数据结构和算法的结合 2.restful规范 定义:url唯一定位资源,http请求方式区分用户行为 (1)接口设计规范 (2)返回数据规范 (3)错误消息规 ...

  8. K8s集群部署(四)------ Flannel网络部署

    所有节点都要部署Flannel网络,在所有节点操作. 1.为Flannel生成证书 [root@k8s-master ssl]# pwd /usr/local/src/ssl [root@k8s-ma ...

  9. Python连载20-偏函数&zip函数&enumerate函数

    一. 偏函数 二. #先举个例子 #把字符串转换为十进制数字 int(') #help(int),int函数中有一个参数base代表把它转换某个进制的数字 #把八进制的字符串转换为十进制 eight ...

  10. 破坏之王-DDoS攻击与防范深度剖析

    破坏之王-DDoS攻击与防范深度剖析 下载:链接:https://pan.baidu.com/s/1bzVT6YkZGGg7anpQWDknjA 提取码:j7ns 网际空间的发展带来了机遇,也带来了威 ...