传递,题解
Posted wish-all-ac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传递,题解相关的知识,希望对你有一定的参考价值。
题目:
Hint
分析:
首先知道题意之后,我们考虑一下传递的图有什么性质:如果a到b有路径,则a到b有只过一条边的路径,证明如果a到b有路径a到x1到x2到...到b的路径,那么根据定义a一定有直接到x2的边,即必有路径a到x2到...到b,同理,a必有到x3的边,a必有到b的边。
即a所能到达的节点都能一次到达,那么我们就对每个点BFS一下就好了,第二次可以拓展就不是传递的,只能拓展一次就是传递的。当然两个图分开处理。
代码:
#include <cstdio> #include <cstring> const int maxn=2016+10; char s[maxn][maxn]; struct E{ int to; int next; }ed[maxn*maxn]; int head[maxn]; int tot; int vis[maxn]; void J(int a,int b){ tot++; ed[tot].to=b; ed[tot].next=head[a]; head[a]=tot; } E ed0[maxn*maxn]; int head0[maxn]; int tot0; void J0(int a,int b){ tot0++; ed0[tot0].to=b; ed0[tot0].next=head0[a]; head0[a]=tot0; } int a[maxn]; int to; bool Bfs(int x){ memset(vis,0,sizeof(vis)); vis[x]=1; to=0; for(int i=head[x];i;i=ed[i].next){ to++; a[to]=ed[i].to; vis[ed[i].to]=1; } while(to){ int s=a[to]; to--; for(int i=head[s];i;i=ed[i].next) if(!vis[ed[i].to]) return 1; } return 0; } bool Bfs0(int x){ memset(vis,0,sizeof(vis)); vis[x]=1; to=0; for(int i=head0[x];i;i=ed0[i].next){ to++; a[to]=ed0[i].to; vis[ed0[i].to]=1; } while(to){ int s=a[to]; to--; for(int i=head0[s];i;i=ed0[i].next) if(!vis[ed0[i].to]) return 1; } return 0; } int main(){ int t; scanf("%d",&t); for(int i=1;i<=t;i++){ int n; scanf("%d",&n); tot=0; tot0=0; memset(head,0,sizeof(head)); memset(head0,0,sizeof(head0)); for(int i=1;i<=n;i++){ getchar(); for(int j=1;j<=n;j++){ s[i][j]=getchar(); if(s[i][j]==‘P‘) J(i,j); else if(s[i][j]==‘Q‘) J0(i,j); } } bool bj=0; for(int i=1;i<=n;i++) if(Bfs(i)){ bj=1; break; } tot=0; if(bj){ printf("N "); continue; } for(int i=1;i<=n;i++) if(Bfs0(i)){ bj=1; break; } if(bj) printf("N "); else printf("T "); } return 0; }
以上是关于传递,题解的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 C 代码片段不起作用?简化版可以。为 unsigned long long 传递不带 VA_ARGS 的 args
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段