标签:getchar break har bool mamicode == eof 定义 string
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\n"); continue; } for(int i=1;i<=n;i++) if(Bfs0(i)){ bj=1; break; } if(bj) printf("N\n"); else printf("T\n"); } return 0; }
标签:getchar break har bool mamicode == eof 定义 string
原文地址:https://www.cnblogs.com/wish-all-ac/p/12916167.html