1002. Is It Acyclic

Description

Given a directed graph, decide if it is acyclic (there is no directed cycle).

Input

There are multiple test cases. The first line contains an integer T, indicating the number of test cases. Each test case begins with a line containing two integers, 1 <= n <= 100000 and 1 <= m <= 100000. n is the number of vertices (numbered from 1 to n) and m is the number of direct precedence relations between vertices. After this, there will be m lines with two integers i and j, representing that there is a directed edge from vertex i  to vertex j.

Output

For each test case, print a line "It is acyclic." or "There exists a cycle.".

 

Sample Input
 Copy sample input to clipboard 
2
3 3
1 2
2 3
3 1
5 5
3 4
4 1
3 2
2 4
5 3 
Sample Output
There exists a cycle.
It is acyclic.

判断有向图中是否存在环,用拓扑排序,用DFS会超时; 拓扑排序时,如果所有顶点都被访问到,则无环;反之有环。
此外还要注意题目中的限制条件。
#include <iostream>
#include <vector>
#include <list>
#include <queue>
using namespace std;

struct Graph {
    vector<list<int> > adj;
    int v, e;
    int indgree[100001];// 存储顶点的入度
};

//初始化图
void makeGraph(Graph* &g) {
    int m, n;
    cin >> m >> n;
    g->v = m;
    g->e = n;
    for (int i = 1; i <= g->v; ++i) {
        g->indgree[i] = 0;
    }
    for (int i = 1; i <= g->e; ++i) {
        int a, b;
        cin >> a >> b;
        g->adj[a].push_back(b);
        g->indgree[b]++;
    }
}

//拓扑排序
void topology(Graph* &g) {
    queue<int> q; //用队列存储入度为0的顶点
    int count = 0;
    for (int i = 1; i <=g->v; ++i) {
        if (g->indgree[i] == 0) {
            q.push(i);
            ++count;
        }
    }
    while (!q.empty()) {
        int a = q.front();
        q.pop();
        //遍历顶点的邻接表,每一次都将入度减一
        list<int>::iterator it = g->adj[a].begin();
        while (it != g->adj[a].end()) {
            g->indgree[*it]--;
            if (g->indgree[*it] == 0) {
                q.push(*it);
                count++;
            }
            *it++;
        }
    }
    if (count == g->v) {
        cout << "It is acyclic." << endl;
    }
    else
        cout << "There exists a cycle." << endl;
}

int main(int argc, const char * argv[]) {
    int cases;
    cin >> cases;
    for (int i = 0; i < cases; ++i) {
        Graph *g = new Graph;
        g->adj.resize(100001);
        makeGraph(g);
        topology(g);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值