热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

判断有向图是否存在3元环并进行拓扑排序

题目大意:给你一个关系图,判断是否合法,每个人都有师父和徒弟,可以有很多个;但是你的师父不能是你徒弟的徒弟,或者说你的徒弟不能是你师父的师父,这是不合法的情况。简单理解就是:判断有

题目大意:

   给你一个关系图,判断是否合法,

  每个人都有师父和徒弟,可以有很多个;

  但是你的师父不能是你徒弟的徒弟,或者说你的徒弟不能是你师父的师父,这是不合法的情况。

  简单理解就是:判断有向图中是否存在3元环;

  此题至少有三种做法,此处跟新拓扑排序的做法:

1. 拓扑排序:

  1. 统计每个点的入度;

   2. 将入度为0的点加入队列;

    3. 出去队首元素,将此元素所连接的点入度减一,若此后入度为0则加入队列;

   4. 判断队列循环次数,若等于n则不存在3元环,则此关系图合法;

题目链接:

点击打开链接

#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
using namespace std;  
const int  N = 2005;
const int  M = 3000005;
int n,m;
int tot,flag;
int in[N],head[N];
struct lp
{
    int u,v,nex;
    lp(){}
    lp(int a,int b,int c):
    u(a),v(b),nex(c){}
}cw[N];
void add(int a,int b){
    cw[++tot]=lp(a,b,head[a]);
    head[a]=tot;
}
void tuopu(){
    queue<int>Q;
    while(!Q.empty())Q.pop();
    for(int i=0;ii){
        if(in[i]==0)Q.push(i);
    }
    int t=0;
    while(!Q.empty()){
        t++;
        int u=Q.front();Q.pop();
        for(int i=head[u];i!=-1;i=cw[i].nex){
            int v=cw[i].v;
            in[v]--;
            if(in[v]==0)Q.push(v);
        }
    }
    if(t==n)flag=1;
}
int main(int argc, char const *argv[])
{
    int a,b;
    while(~scanf("%d%d",&n,&m)&&(n)){
        memset(in,0,sizeof(in));
        tot=-1;
        memset(head,-1,sizeof(head));
        for(int i=0;ii){
            scanf("%d%d",&a,&b);
            add(a,b);
            in[b]++;
        }
        flag=0;
        tuopu();
        if(flag)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
View Code

 


推荐阅读
author-avatar
开在覀黎明前的小茉莉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有