用C语言解决问题。【题目描述】给定无权有向图G(V,E),请判断G是否是一个有向无环图(DAG)。 【输入格式】 第一行包含两个整数N、M,表示该图共有N个结点和M条有向边。(N <= 5000,M <= 200000) 接下来M行,每行包含2个整数{u,v},表示有一条有向边(u,v) 【输出格式】 有环输出“not DAG”,无环输出“DAG” 【输入样例】 5 7 1 2 1 5 2 3 3 1 3 2 4 1 4 5 【输出样例】 not DAG not DAG
时间: 2024-02-15 20:01:52 浏览: 74
以下是该题的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 5000
#define MAX_M 200000
int n, m;
int in_degree[MAX_N];
int adj_list[MAX_N][MAX_N];
int queue[MAX_N], head, tail;
int is_DAG() {
int i, u, v;
int count = 0;
head = tail = 0;
// 将入度为0的点加入队列
for (i = 0; i < n; i++) {
if (in_degree[i] == 0) {
queue[tail++] = i;
}
}
// 拓扑排序
while (head < tail) {
u = queue[head++];
count++;
for (i = 0; i < in_degree[u]; i++) {
v = adj_list[u][i];
if (--in_degree[v] == 0) {
queue[tail++] = v;
}
}
}
return count == n;
}
int main() {
int i, u, v;
scanf("%d%d", &n, &m);
// 初始化入度表和邻接表
for (i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
in_degree[v-1]++;
adj_list[u-1][in_degree[u-1]-1] = v-1;
}
// 判断是否为DAG
if (is_DAG()) {
printf("DAG\n");
} else {
printf("not DAG\n");
}
return 0;
}
```
算法思路:
- 先根据输入的边列表构建每个点的入度表和邻接表;
- 将所有入度为0的点加入队列中;
- 使用BFS拓扑排序遍历每个点,每当从队列中弹出一个点时,就遍历其所有的后继节点,并将其入度减1;如果某个点的入度变为0,则将其加入队列中;
- 最终统计遍历的点数count,如果count等于总点数n,则说明图是DAG,否则不是DAG。
阅读全文