zoukankan      html  css  js  c++  java
  • 传递,题解

    题目:

      

      

      

      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;
    } 
  • 相关阅读:
    Python基础之只接收关键字参数的函数
    Python基础之可接受任意数量参数的函数
    Django基础之创建admin账号
    GIT版本控制工具
    全站导航
    python中对url编码解码处理
    VUE安装及初始化报错解决办法
    使用Appium+python爬取手机App
    python发送QQ邮件
    docker部署flask项目
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12916167.html
Copyright © 2011-2022 走看看