Acwing 3696-构造有向无环图 / 拓扑排序 / 指定无向边的方向,让其和有向边一起构造成一个拓扑图
Acwing 3696-构造有向无环图
开始想了半天没想明白,后来突然想到这个题目这个名称,或许是一个模板题
。我不知道是不是模板题,但我当模板题记下来
,因为我理解不了。
操作:
1. 读边时有向边指向的点入度增加,无向边入度都为 0, 用结构体存下所有无向边
2. 进行一次 top_sort,只要点入度为 0,就加入队列,不管这个入度为 0 的点是有向边的点还是无向边的点,且给依次出队的点标序 (pos[t] = order ++ )
3. 如果 top_sort 后出队的点的总数为总点数,则可以构造一个有向无环图,然后才进行下面的 4,5
4. 枚举所有点,输出有向边的点的所有边
5. 枚举存放无向边的结构体的所有边,对于每条无向边里的 a,b两点,pos 小的先输出,pos 大的后输出
#include <iostream> #include <cstring> #include <queue> using namespace std; const int N = 2e5 + 10, M = N; int e[M], ne[M], h[N], idx; int d[N], pos[N]; int n, m, T; int u; struct node { int a, b; }edge[M]; // 存无向边 void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ; } int top_sort() { queue<int>q; for (int i = 1; i <= n; i ++ ) if (d[i] == 0) q.push(i); int order = 0, sum = 0; while (q.size()) { int t = q.front(); q.pop(); sum ++ ; pos[t] = order ++ ; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; d[j] -- ; if (d[j] == 0) q.push(j); } } return sum == n; } int main() { cin >> T; while (T -- ) { idx = 0, u = 0; memset(h, -1, sizeof h); memset(d, 0, sizeof d); scanf("%d%d", &n, &m); while (m -- ) { int type, a, b; scanf("%d%d%d", &type, &a, &b); if (type == 1) add(a, b), d[b] ++ ; else edge[u ++ ] = {a, b}; } int t = top_sort(); if (t == 0) printf("NO\n"); else { printf("YES\n"); for (int k = 1; k <= n; k ++ ) for (int i = h[k]; i != -1; i = ne[i]) printf("%d %d\n", k, e[i]); for (int i = 0; i < u; i ++ ) { int a = edge[i].a, b = edge[i].b; if (pos[a] < pos[b]) printf("%d %d\n", a, b); else printf("%d %d\n", b, a); } } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】