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;
    } 
  • 相关阅读:
    SendMessage操作另一个EXE,存在这,以后也许用得着。
    六、Delphi 2009 泛型容器单元(Generics.Collections)[5]: TObject...<T> 系列
    闲扯原码、反码、补码
    限制edit只能输入数字
    动态创建TXMLDocument对XML文件进行读取和写入
    XML操作
    Ubuntu下配置lazarus开发环境
    C#结构体(二)
    【转】 如何有效減少Nios II EDS所編譯程式碼大小? (IC Design) (Nios II)
    关于NiosII和Win7系统兼容性的问题处理方式
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12916167.html
Copyright © 2011-2022 走看看