【XSY2525】Maze 2017多校
Description
考虑一个 N×M 的网格,每个网格要么是空的,要么是障碍物。整个网格四周都是墙壁(即第1行和第n行,第1列和第m列都是墙壁),墙壁有且仅有两处开口,分别代表起点和终点。起点总是在网格左边,终点总是在网格右边。你只能朝4个方向移动:上下左右。数据保证从起点到终点至少有一条路径。
从起点到终点可能有很多条路径,请找出有多少个网格是所有路径的必经网格。
Input
第一行包含两个整数 N,M ,表示网格 N 行 M 列。
接下来 N 行,每行 M 个字符,表示网格。'#'表示障碍物或墙壁,'.'表示空地。
Output
输出文件包含一个整数,必经点的个数。
Sample Input
7 7
#######
....#.#
#.#.###
#.....#
###.#.#
#.#....
#######
Sample Output
5
HINT
样例解释
(2, 1) (2, 2) (4, 4) (6, 6) (6, 7)
数据范围与约定
对于10%的数据, 3≤N,M≤50
对于50%的数据, 3≤N,M≤500
对于所有数据, 3≤N,M≤1000
前置知识——tarjan算法
看一下题。
题目中说了,要求所有路径的必经网格,这种描述好像跟某一种算法要求的结果相同,是什么呢?
——割点。
我们想一下,如果一个点是所有路径的必经网格,那么如果我们去掉这个点会怎么样?
——起点和终点不联通了。
这就很像我们的割点和割边了。
在一个连通图中,如果我们去掉一个点或一条边,使得剩下的图变得有一部分不连通,那么这个点或这条边就被称为割点(边)。
这是不是很像这道题。
那我们就说一下这道题的解法。
我们枚举每一个不为‘#’的点,每个点与他周围不为‘#’的边连边,然后求出这个图的割点数(不算起点和终点),把答案加2(起点和终点),输出。
是不是觉得有点道理?
但是,这样做有很大的错误。
看一下这张图

如图,按照上面这种算法,涂红色的点都应该是答案,但依照题目,只有最上面的红点和起(终)点是答案。
所以,单纯的求割点是不能的到正确答案的。
我们应该在tarjan中加一个判断这段路的末尾是否是终点,我们才把这段路上的割点设为答案。
#include<bits/stdc++.h>
#define N 1000000
using namespace std;
int nct,cnt,number[N],ans,dfn[N],low[N],indew,to[N*20],head[N],nxt[N*20],yes[N],root,n,m,is[1001][1001],f[4][2]={{1,0},{0,1},{-1,0},{0,-1}},ed;
char ch[2001];
bool viss[N];
void adde(int u,int v)
{
to[++nct]=v;
nxt[nct]=head[u];
head[u]=nct;
}
bool tarjan(int u,int fa)
{
int child=0;
dfn[u]=low[u]=++indew;
bool flag=0;//u这条路的末尾是否是终点
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(v==fa)
{
continue;
}
bool fflag=0;//v这条路的末尾是否是终点
if(!dfn[v])
{
if(tarjan(v,u))
{
flag=fflag=1;
}
if(low[v]>=dfn[u]&&fflag)
{
yes[u]=1;//是答案的割点
}
low[u]=min(low[v],low[u]);
child++;
}else{
low[u]=min(low[u],dfn[v]);
}
}
if(fa==-1&&child<2)
{
yes[u]=0;
}
return flag||(u==ed);//回溯
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",ch);
for(int j=0;j<m;j++)
{
if(ch[j]=='.')
{
is[i][j+1]=1;
}
}
}
for(int i=2;i<n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<=3;k++)
{
int xx=i+f[k][0],yy=j+f[k][1];
if(!is[xx][yy]||!is[i][j])
{
continue;
}
if(!viss[(i-1)*m+j])//编号
{
number[(i-1)*m+j]=++cnt;
viss[(i-1)*m+j]=1;
}
if(!viss[(xx-1)*m+yy])
{
number[(xx-1)*m+yy]=++cnt;
viss[(xx-1)*m+yy]=1;
}
if(j==1&&!root)//求起点
{
root=number[(i-1)*m+j];
}
if(yy==1&&!root)
{
root=number[(xx-1)*m+yy];
}
if(j==m&&!ed)//求终点
{
ed=number[(i-1)*m+j];
}
if(yy==m&&!ed)
{
ed=number[(xx-1)*m+yy];
}
adde(number[(i-1)*m+j],number[(xx-1)*m+yy]);//连边
}
}
}
tarjan(root,-1);//tarjan求割点
for(int i=1;i<=cnt;i++)
{
if(yes[i])
{
ans++;
}
}
ans+=2;
printf("%d\n",ans);
return 0;
}
/*
7 7
#######
....#.#
#.#.###
#.....#
###.#.#
#.#....
#######
*/
【XSY2525】Maze 2017多校的更多相关文章
- 2017 多校5 hdu 6093 Rikka with Number
2017 多校5 Rikka with Number(数学 + 数位dp) 题意: 统计\([L,R]\)内 有多少数字 满足在某个\(d(d>=2)\)进制下是\(d\)的全排列的 \(1 & ...
- 2017 多校5 Rikka with String
2017 多校5 Rikka with String(ac自动机+dp) 题意: Yuta has \(n\) \(01\) strings \(s_i\), and he wants to know ...
- 2017 多校4 Wavel Sequence
2017 多校4 Wavel Sequence 题意: Formally, he defines a sequence \(a_1,a_2,...,a_n\) as ''wavel'' if and ...
- 2017 多校4 Security Check
2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...
- 2017 多校3 hdu 6061 RXD and functions
2017 多校3 hdu 6061 RXD and functions(FFT) 题意: 给一个函数\(f(x)=\sum_{i=0}^{n}c_i \cdot x^{i}\) 求\(g(x) = f ...
- 2017 多校2 hdu 6053 TrickGCD
2017 多校2 hdu 6053 TrickGCD 题目: You are given an array \(A\) , and Zhu wants to know there are how ma ...
- 2017 多校1 I Curse Myself
2017 多校2 I Curse Myself(第k小生成树) 题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k ...
- hdu6136[模拟+优先队列] 2017多校8
有点麻烦.. /*hdu6136[模拟+优先队列] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long ...
- hdu6134[莫比乌斯反演] 2017多校8
/*hdu6134[莫比乌斯反演] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long long LL ...
随机推荐
- 夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 利用双重检查锁定和CAS算法:解决并发下数据库的一致性问题
背景 最近有一个场景遇到了数据库的并发问题.现在先由我来抽象一下,去掉不必要的繁杂业务. 数据库表book存储着每本书的阅读量,一开始数据库是空的,不存在任何的数据.当用户访问接口的时候,判断 ...
- python编程基础之十八
字符串的查找和替换常用函数: str.count(sub,start = 0,end = len(str)) 计算sub 在str中出现的次数,[start,end)寻找区间 str.find(str ...
- 超详细!! sql server 同步数据库 发布 订阅 跨网段 无公网ip 常见问题
问题描述 主机1:发布端 阿里云服务器--有公网ip 主机2:订阅端 笔记本--无公网ip 数据量很小,主要是熟悉发布订阅的操作流程. 主机2仅仅作为主机1的本地备份,要求修改云服务器上数据后,能通过 ...
- CSS3 入门到精通(一)
CSS 用于控制网页的样式和布局. CSS3 是最新的 CSS 标准. 一. CSS3边框 实例 向 div 元素添加圆角: div { border:2px solid; border-radius ...
- 用 Python 爬取网易严选妹子内衣信息,探究妹纸们的偏好
网易商品评论爬取 分析网页 评论分析 进入到网易精选官网,搜索“文胸”后,先随便点进一个商品. 在商品页面,打开 Chrome 的控制台,切换至 Network 页,再把商品页Python入门到精通学 ...
- 本人亲测-SSM整合后的基础包(供新手学习使用,可在本基础上进行二次开发)
本案例是在eclipse上进行开发的,解压后直接添加到eclipse即可.还需要自己配置maven环境.链接:https://pan.baidu.com/s/1siuvhCJASuZG_jqY5utP ...
- Python3实战spark大数据分析及调度 ☝☝☝
Python3实战spark大数据分析及调度 ☝☝☝ 一.实例分析 1.1 数据 student.txt 1.2 代码 二.代码解析 2.1函数解析 2.1.1 collect() RDD的特性 在 ...
- php反序列化漏洞复现过程
PHP反序列化漏洞复现 测试代码 我们运行以上代码文件,来证明函数被调用: 应为没有创建对象,所以构造函数__construct()不会被调用,但是__wakeup()跟__destruct()函数都 ...
- 微信小程序之媒体查询@media
微信小程序支持媒体查询,代码如下: @media screen and (min-width: 700px) { .container { padding: 30rpx; } } @media scr ...