zoukankan      html  css  js  c++  java
  • 【图论】HDU 5961 传递

    题目内容

    题目链接
    我们称一个有向图G是传递的当且仅当对任意三个不同的顶点a,若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c。
    我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句 话说,将完全图每条边定向将得到一个竞赛图。
    下图展示的是一个有4个顶点的竞赛图。
    avatar
    现在,给你两个有向图P=(V,(E_p))和Q=(V,(E_e)),满足:

    1. (E_P)(E_e)没有公共边;
    2. (V,(E_p⋃E_e))是一个竞赛图。
      你的任务是:判定是否P,Q同时为传递的。

    输入格式

    包含至多20组测试数据。
    第一行有一个正整数,表示数据的组数。
    对于每组数据,第一行有一个正整数(n)。接下来(n)行,每行为连续的(n)个字符,每 个字符只可能是-,P,Q中的一种。

    • 如果第(i)行的第(j)个字符为P,表示有向图P中有一条边从(i)(j);
    • 如果第(i)行的第(j)个字符为Q,表示有向图Q中有一条边从(i)(j);
    • 否则表示两个图中均没有边从(i)(j)
      保证(1le nle 2016),一个测试点中的多组数据中的(n)的和不超过16000。保证输入的图一定满足给出的限制条件。

    样例

    见链接

    样例解释

    在下面的示意图中,左图为图为Q。
    avatar
    注:在样例2中,P不是传递的。在样例4中,Q不是传递的。

    输出格式

    对每个数据,你需要输出一行。如果P,Q都是传递的,那么请输出T。否则, 请输出N

    思路

    若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c。

    如果bfs搜到了长度超过1的路径,就意味着图不是传递的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2020;
    
    struct Edge{
        int from,to,nxt;
    }p[maxn*maxn],q[maxn*maxn];
    
    int vis[maxn];
    char s[maxn];
    struct node{
        int num,sum;
    }now;
    bool flag;
    int n;
    
    int cntq=1,cntp=1;
    int headp[maxn],headq[maxn];
    void addp(int a,int b){
    	p[cntp].from=a;
        p[cntp].to=b;
        p[cntp].nxt=headp[a];
        headp[a]=cntp++;
    }
    
    void addq(int a,int b){
    	q[cntq].from=a;
        q[cntq].to=b;
        q[cntq].nxt=headq[a];
        headq[a]=cntq++;
    }
    
    void bfsp(){
        for(int i=0;i<n;i++){
            if(headp[i]!=-1){
                memset(vis,0,sizeof(vis));
                queue<node>que;
                que.push(node{i,0});
                while(!que.empty()){
                    now=que.front();
                    que.pop();
                    if(now.sum>=2){
                        flag=false;
                        return;
                    }
                    for(int j=headp[now.num];j!=-1;j=p[j].nxt){
                        if(vis[p[j].to]==0){
                            vis[p[j].to]=1;
                            que.push(node{p[j].to,now.sum+1});
                        }
                    }
                }
            }
        }
    }
    
    void bfsq(){
        for(int i=0;i<n;i++){
            if(headq[i]!=-1){
                memset(vis,0,sizeof(vis));
                queue<node>que;
                que.push(node{i,0});
                while(!que.empty()){
                    now=que.front();
                    que.pop();
                    if(now.sum>=2){
                        flag=false;
                        return;
                    }
                    for(int j=headq[now.num];j!=-1;j=q[j].nxt){
                        if(vis[q[j].to]==0){
                            vis[q[j].to]=1;
                            que.push(node{q[j].to,now.sum+1});
                        }
                    }
                }
            }
        }
    }
    
    int main() {
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            memset(headp,-1,sizeof(headp));
            memset(headq,-1,sizeof(headq));
            for(int i=0;i<n;i++){
                scanf("%s",s);
                for(int j=0;j<n;j++){
                    if(s[j]=='P'){
                        addp(i,j);
                    }else if(s[j]=='Q'){
                        addq(i,j);
                    }
                }
            }
    
            flag=true;
            bfsp();
            if(flag)bfsq();
            if(flag)printf("T
    ");
            else printf("N
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    浅尝辄止——在C++中调用C#的回调函数——COM方式
    代码管理——如何连接Git Server,下载代码
    浅尝辄止——使用ActiveX装载WPF控件
    软件调试——CPU异常列表
    软件调试——IA-32 保护模式下寄存器一览
    Delphi面向对象编程
    看雪2017CTF第二题解法
    串操作指令
    MASM 重复汇编
    MASM 宏结构
  • 原文地址:https://www.cnblogs.com/Midoria7/p/12929743.html
Copyright © 2011-2022 走看看