zoukankan      html  css  js  c++  java
  • 【四校联考】传递

    【题解】

    如果一个图是竞赛图那么如果存在边<a,b>,那么a一定能走到b,反之亦然

    还有,如果在图P中存在边<a,b>,那么图Q中一定不存在边<a,b>或<b,a>(基图是完全图)

    那么,如果图P中存在边<a,b>,图Q一定不能从a走到b或者从b走到a

    既然如此,因为图P+图Q是完全图

    所以,对于点u和点v,u和v之间的边要不然在P里,要不然在Q里,

    所以要不然只能从u走到v,要不然只能从v走到u,

    那么,这不就是一个DAG嘛

    于是我们把Q里的边分别正着反着加入P

    判断是不是DAG即可

    #include<stdio.h>
    #include<stdlib.h>
    #include<iostream>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    #include<map>
    #include<vector>
    #include<set>
    #define il inline
    #define re register
    using namespace std;
    const int N=3001;
    int n,in[N],T;
    bool s[N][N],p[N][N],q[N][N],d[N][N];
    queue<int> que;
    il bool chk(){
        memset(in,false,sizeof(in));
        for(re int i=1;i<=n;i++){
            for(re int j=1;j<=n;j++)
                in[j]+=d[i][j];
        }
        for(int i=1;i<=n;i++)
            if(!in[i]) que.push(i);
        while(!que.empty()){
            re int h=que.front();que.pop();
            for(re int i=1;i<=n;i++) if(d[h][i]){
                in[i]--;
                if(!in[i]){
                    que.push(i);
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(in[i]) return false;
        }
        return true;
    }
    il void init(){
        memset(p,false,sizeof(p));
        memset(q,false,sizeof(q));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]+1);
            for(int j=1;j<=n;j++){
                if(s[i][j]=='P') p[i][j]=1;
                else if(s[i][j]=='Q') q[i][j]=1;
            }
        }
        memset(d,false,sizeof(d));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(p[i][j]) d[i][j]=1;
                if(q[i][j]) d[i][j]=1;
            }
        if(!chk()){
            printf("N
    ");return;
        }
        memset(d,false,sizeof(d));
        for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++){
                if(p[i][j]) d[i][j]=1;
                if(q[i][j]) d[j][i]=1;
            }
        if(!chk()){
            printf("N
    ");return;
        }
        printf("T
    ");
    }
    int main(){
        freopen("trans.in","r",stdin);
        freopen("trans.out","w",stdout);
        scanf("%d",&T);
        for(int i=1;i<=T;i++) init();
        return 0;
    }
  • 相关阅读:
    WebSocket来实现即时通讯
    微信小程序1
    使用phpqrcode来生成二维码/thinkphp
    PHP函数积累
    Docker 常用命令汇总(beta)
    Nginx+Keepalived高可用架构简述(beta)
    Docker镜像制作(以Nginx+Keepalived为例)(beta)
    开源协议浅谈(beta)
    【Elasticsearch系列】ES安装(mac)
    linux 下安装JDK
  • 原文地址:https://www.cnblogs.com/ExiledPoet/p/6075371.html
Copyright © 2011-2022 走看看