Given a directed graph, decide if it is acyclic (there is no directed cycle).
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.
For each test case, print a line "It is acyclic." or "There exists a cycle.".
2 3 3 1 2 2 3 3 1 5 5 3 4 4 1 3 2 2 4 5 3
There exists a cycle. It is acyclic.
#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);
}
}