Hdu 5961 传递

Hdu 5961 传递(bfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5961
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解题思路:
题目最重要的一句话,如下图.
在这里插入图片描述
只有a->b,b->c,一定存在a->c,那么就很容易处理了,只要把a连接的所有点标记掉,那如果图是传递的,就不存在其他点能通过a连接的点到达,反之图就不是传递的,即如果bfs搜到了长度超过1的路径,就意味着图不是传递的。
代码如下:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2025
struct Edge{
    int from,to,nex;
}p[MAXN*MAXN],q[MAXN*MAXN];//邻近表
int ans,cnt;
int headp[MAXN],headq[MAXN];
int vis[MAXN];
char s[MAXN];
struct node{
    int num,sum;//点,次数
}now;
bool flag;
int n;
inline void bfs(){//检查图P
    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){//如果sum>=2就意味着有一个点a->b,b->c,而a不能直接到c,那就是不符合题意的
                    flag=false;
                    return;
                }
                for(int j=headp[now.num];j!=-1;j=p[j].nex){
                    if(vis[p[j].to]==0){
                        vis[p[j].to]=1;//重点,其实就是为了标记起点连接的所有点
                        que.push(node{p[j].to,now.sum+1});
                    }
                }
            }
        }
    }
}
inline void bfs1(){//检查图Q
    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].nex){
                    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);
        cnt=1,ans=1;
        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'){
                    p[cnt].from=i;
                    p[cnt].to=j;
                    p[cnt].nex=headp[i];
                    headp[i]=cnt++;
                }else if(s[j]=='Q'){
                    q[ans].from=i;
                    q[ans].to=j;
                    q[ans].nex=headq[i];
                    headq[i]=ans++;
                }
            }
        }
        flag=true;
        bfs();
        if(flag)bfs1();//优化,仅当图P是传递的才检查图Q
        if(flag)printf("T\n");
        else printf("N\n");
    }
    return 0;
}
发布了35 篇原创文章 · 获赞 3 · 访问量 888

猜你喜欢

转载自blog.csdn.net/weixin_43823753/article/details/104600260
hdu