[codevs5578][咸鱼]tarjan/结论题

时间:2022-01-07 19:46:44

5578 咸鱼

 时间限制: 1 s
 空间限制: 128000 KB
题目描述 Description

在广袤的正方形土地上有n条水平的河流和m条垂直的河流,发达的咸鱼家族在m*n个河流交叉点都建立了城市。然而,由于河流有单一的流向,而咸鱼们却没有发达的下体,所以只能顺流而下。两两河流之间的流向互不影响。

现在,咸鱼冒险家Sorey决定出发去看看这个世界,但是Sorey担心自己可能被困在某个城市而无法回归自己的家乡。于是Sorey夜观天象,搞清楚了每条河的流向,他想请你帮他判断他的旅途是否会顺利。

输入描述 Input Description

第一行一个整数T,表示数据组数(T<=10)

每组数据第一行两个整数n,m,含义如上述

第二行两个整数x,y,表示Sorey的初始坐标(从一开始,x表示所在行,y表示所在列)

下一行n个数,之间用空格间隔,其中第i个表示第i条水平河流的方向,0向左,1向右

下一行m个数,之间用空格间隔,其中第i个表示第i条垂直河流的方向,0向下,1向上

输出描述 Output Description

一组数据一行

如果Sorey能到达任何一座城市且不可能被困住的话,输出"Yes.",否则输出"No."(不含引号)

样例输入 Sample Input

1

4 6

1 1

0 1 0 1

0 1 0 1 0 1

样例输出 Sample Output

Yes.

数据范围及提示 Data Size & Hint

样例如图

[codevs5578][咸鱼]tarjan/结论题

对于40%的数据n,m<100,T=1;

对于60%的数据n,m<1000;

对于100%的数据2<=n,m<=1000000,1<=x<=n,1<=y<=m;

数据很大,注意读入优化

分析:

“咸鱼们却没有发达的下体”以及Yes后面的句号,槽点还是挺多的。数据范围很大,应该是结论题

推论1:

  看这句话“但是Sorey担心自己可能被困在某个城市而无法回归自己的家乡”以及“如果Sorey能到达任何一座城市且不可能被困住的话,输出"Yes.",否则输出"No."(不含引号)”,显然题目要求我们判断是否可以从源点s到任何一个点且可以从任何一个点回到源点s,即任意两点i,j互相可达(i到s,再s到j),所以,要求原图是强连通分量。用tarjan算法即可判断。但是复杂度O(nm),只有60分。

推论2:

  我们必须优化到O(n)或以下,考虑特判,看了一下样例发现:只需要最外围是一个环就一定满足,因为从s沿边走就一定可以到外围,在外围绕圈到每一条边的入口即可进去。

推论3:

  充分性已证,只需完备性即可:只要最外围不是环,那么四个顶角必然有的只能进不能出,不可能是强连通分量。

  现在只需要判断最外围是不是环即可,复杂度O(1),但数据太大,要优化读入,可以用fseek跳过中间部分,用getchar()也能过(偷懒的我用的后者,复杂度O(n+m))

 #include<cstdio>
inline int read(){
char c=getchar();
while(c!=''&&c!='') c=getchar();
return c-'';
}
int main(){
int n,m,x,y,a,b,c,d,T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d %d",&n,&m,&x,&y);
a=read();n-=;
while(n--) read();
b=read();c=read();m-=;
while(m--) read();
d=read();
if((a==&&b==&&c==&&d==)||
(a==&&b==&&c==&&d==)) printf("Yes.\n");
else printf("No.\n");
}
return ;
}