1 条题解
-
0
自动搬运
来自洛谷,原作者为

luan341502
AFOed搬运于
2025-08-24 22:50:21,当前版本为作者最后更新于2023-09-18 23:25:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
赛时交了八发才过,少考虑了一种情况。
考虑将每个点对应能到的点连起来,这样就构成了一张图(如果对于不满足题目条件的点不进行连边的话,就无法构成一棵基环树)。
观察可以发现只有两种情况满足题目要求:
-
整个图构成一个环,此时从任意点出发都能经过所有点。
-
从一个点出发到达一个环,最终遍历完整个图。
对于两种情况分别判断,用并查集记录即可。
-
所有点在一个并查集内就满足情况。
-
只有一个点入度为零,否则一定不满足情况。统计入度情况进行判断即可。
由于 ,考虑使用将矩阵映射为直线的做法,这样只需开长度为 的一维数组。
#include<bits/stdc++.h> using namespace std; int n,m; string str[100005]; int fa[100005],d[100005]; int find(int x){ if(fa[x]==x) return x; return fa[x]=find(fa[x]); } void merge(int x,int y,int x_,int y_){ int s1=(x-1)*m+y,s2=(x_-1)*m+y_; int u=find(s1),v=find(s2); if(u!=v) fa[v]=u; } void solve(){ scanf("%d%d",&n,&m); for(int i=1;i<=n*m;i++){ fa[i]=i; d[i]=0; } for(int i=1;i<=n;i++){ cin>>str[i]; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int x; scanf("%d",&x); int ch=(int)str[i][j-1],p,q; if(ch==117) p=i-x,q=j; else if(ch==100) p=i+x,q=j; else if(ch==108) p=i,q=j-x; else p=i,q=j+x; if(p<1||q<1||p>n||q>m) continue; merge(i,j,p,q); d[(p-1)*m+q]++; } } int x=find(1),cnt=n*m; for(int i=2;i<=cnt;i++){ if(find(i)!=x){ puts("No"); return; } } int res=0; for(int i=1;i<=cnt;i++){ if(!d[i]) res++; if(res>1){ puts("No"); return; } } puts("Yes"); } int main(){ int t; cin>>t; while(t--){ solve(); } return 0; } -
- 1
信息
- ID
- 9188
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者