• 【图论】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;
    }
    
  • 相关阅读:
    如何利用排班实现告警的灵活分派?
    OneAlert 携手 BearyChat(倍洽)快速构建 IT 运维 on-call 机制
    OneAPM大讲堂 | Metrics, Tracing 和 Logging 的关系
    OneAPM大讲堂 | Java 异常日志记录最佳实践
    从区块链的角度看企业协作
    为什么 APM 能提升 IT 团队工作质量?
    JavaScript中的私有成员[翻译]
    【工作分解法】IT人,你的工作“轻松”么?
    【数据分析】线性回归与逻辑回归(R语言实现)
    【数据分析】贝叶斯原理以及简单案例说明
  • 原文地址:https://www.cnblogs.com/Midoria7/p/12929743.html
Copyright © 2020-2023  润新知