zoukankan      html  css  js  c++  java
  • hihocoder 1174 [BFS /拓扑排序判断是否有环]

    [hihocoder 1174](http://hihocoder.com/problemset/problem/1174) [算法]: 1. 计算每一个点的入度值deg[i],这一步需要扫描所有点和边,复杂度O(N+M)。
    1. 把入度为0的点加入队列Q中,当然有可能存在多个入度为0的点,同时它们之间也不会存在连接关系,所以按照任意顺序加入Q都是可以的。

    2. 从Q中取出一个点p。对于每一个未删除且与p相连的点q,deg[q] = deg[q] - 1;如果deg[q]==0,把q加入Q。

    3. 不断重复第3步,直到Q为空。

    最后剩下的未被删除的点,也就是组成环的点了。
    [代码]:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 10;
    
    int n,m,u,v,num;
    int indeg[maxn];
    vector<int> G[maxn];
    queue<int> q;
    
    bool topSort()
    {
        while(!q.empty()) q.pop(); //清空队列
        num=0; //记住一定要将可以删去的点清0
        for(int i=1;i<=n;i++) if(!indeg[i]) q.push(i); //若一开始的先驱课程没有入度,那么压入队列
        while(!q.empty())
        {
            int now=q.front(); //取出队首
            q.pop();
            num++; //删点++
            for(int i=0; i<G[now].size(); i++) //遍历这个被删去的点的其他相邻结点
            {
                int nxt = G[now][i]; //相邻点
                if( --indeg[nxt] == 0 ) q.push(nxt); //if判断的是:相邻结点的入度--,若为0了,就压入队列作为 下一个要删去的点
            }
        }
        if(num == n) return true; //若点都删去了 说明没有环存在
        else return false;
    }
    
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(indeg,0,sizeof(indeg));
            for(int i=1;i<=n;i++) G[i].clear();
            cin>>n>>m;
            while(m--)
            {
                cin>>u>>v;
                G[u].push_back(v); //将有向边u指向v
                indeg[v]++; //v的入度++
            }
            if(topSort()) puts("Correct"); //无环则ojbk
            else puts("Wrong");
        }
        return 0;
    }
    
    

  • 相关阅读:
    SpringMVC执行原理
    Hello SpringMVC 注解版
    Hello SpringMVC 注解版
    Mybatis一对多和多对一处理
    2020-08-08日报博客
    2020-08-07日报博客
    《大道至简》读后感
    2020-08-06日报博客
    2020-08-05日报博客
    2020-08-04日报博客
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9167620.html
Copyright © 2011-2022 走看看