每日一题之 hiho215周 Circle Detect (拓扑排序)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014046022/article/details/81611299

描述
You are given a directed graph G which has N nodes and M directed edges. Your task is to detect whether it contains any circle.

输入
The first line contains an integer T denoting the number of test cases. (1 <= T <= 5)

For each test case the first line contains two integers N and M. (1 <= N, M <= 100000)

Then follows M lines. Each contains two integers u and v denoting there is an edge from u to v. (1 <= u, v <= N)

输出
For each test case output “YES” or “NO” denoting whether there is a circle in the graph.

样例输入
2
5 5
1 2
2 3
4 5
5 4
4 2
3 2
1 2
2 3
样例输出
YES
NO

题意:

给一个n个点m条边的有向图,判断该图有没有环

思路:

经典的题,直接用拓扑排序来做算法如下:

算法思想

1、在AOV网络中选一个没有直接前驱的顶点, 并入栈(或者输出);

2、从图中删去该顶点, 同时删去所有它发出的有向边;

3、重复以上步骤, 直到

◆ 全部顶点均已输出,拓扑有序序列形成,拓扑排序完成;

◆ 或者图中还有未输出的顶点,但已跳出处理循环。这说明图中还剩下一些顶点,它们都有直接前驱,再也找不到没有前驱的顶点了。这时AOV网络中必定存在有向环。

#include <iostream>
#include <stack>
#include <cstdio>
#include <vector>

using namespace std;


const int maxn = 1e5+5;

struct edge
{
    int to;
};

vector<edge>G[maxn];
int in[maxn];
int n,m;
bool judge()
{   
    stack<int>st;
    for (int i = 1; i <= n; ++i) {
        if (in[i] == 0) {
            st.push(i);
        }
    }
    int cnt = 0;
    while(!st.empty()) {
        auto tmp = st.top();
        st.pop();
        ++cnt;
        for (int i = 0; i < G[tmp].size(); ++i) {
            auto now = G[tmp][i];
            --in[now.to];
            if (in[now.to] == 0) {
                st.push(now.to);
            } 
        }
    }

    if (cnt == n) return true;

    return false;

}

int main()
{
    int t,u,v;
    cin >> t;
    while(t--) {

        cin >> n >> m;
        memset(in,0,sizeof(in));
        for (int i = 0; i < maxn; ++i) G[i].clear();
        for (int i = 0 ; i < m; ++i) {
            cin >> u >> v;
            ++in[v];
            edge tmp;
            tmp.to = v;
            G[u].push_back(tmp);
        }
        if (judge()) cout << "NO" << endl;
        else
            cout << "YES" << endl;
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014046022/article/details/81611299