Acwing 3696. 构造有向无环图 java
🤠 原题地址
🤠 参考链接
🤠 有向边确定了,就直到有没有解了
import java.io.*;
import java.util.Arrays;
public class Main
{
static int N = (int) 2e5 + 10;
// 邻接表存图
static int[] e = new int[N];
static int[] ne = new int[N];
static int[] h = new int[N];
// 存无向边
static Edge[] edges = new Edge[N];
// 存某点的入度
static int[] d = new int[N];
// 队列便于拓扑排序
static int[] q = new int[N];
// 记录每个点的先后顺序
static int[] pos = new int[N];
static int idx, n, m, cnt;
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
static class Edge
{
int a;
int b;
public Edge(int a, int b)
{
super();
this.a = a;
this.b = b;
}
}
/**
* 加一条 a -> b 的边
*
* @param a 起点
* @param b 终点
*/
static void add(int a, int b)
{
// 经典头插法
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
static boolean topSort()
{
int hh = 0;
int tt = -1;
// 队列存入度为 0 的点
for (int i = 1; i <= n; i++)
{
if (d[i] == 0)
q[++tt] = i;
}
while (hh <= tt)
{
int t = q[hh++];
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
d[j]--;
if (d[j] == 0)
{
q[++tt] = j;
}
}
}
// 当 tt == n-1 时,所有数入队,即存在拓扑排序,否则就是并存在有向无环图
return tt == n - 1;
}
public static void main(String[] args) throws IOException
{
int T = Integer.parseInt(in.readLine());
while (T-- > 0)
{
String[] split = in.readLine().split(" ");
n = Integer.parseInt(split[0]);
m = Integer.parseInt(split[1]);
Arrays.fill(h, 0, n + 1, -1);
Arrays.fill(d, 0, n + 1, 0);
idx = 0;
cnt = 0;
// 输入
for (int i = 0; i < m; i++)
{
String[] split2 = in.readLine().split(" ");
int t = Integer.parseInt(split2[0]);
int a = Integer.parseInt(split2[1]);
int b = Integer.parseInt(split2[2]);
if (t == 0)// 无向边
{
edges[cnt++] = new Edge(a, b);
} else
{
add(a, b);
d[b]++;
}
}
//
if (!topSort())
out.write("NO\n");
else
{
out.write("YES\n");
for (int i = 1; i <= n; i++)// 枚举每个点
{
for (int j = h[i]; j != -1; j = ne[j])// 枚举每个点的邻接链表
out.write(i + " " + e[j] + "\n");
}
for (int i = 0; i < n; i++)
{
pos[q[i]] = i;
}
for (int i = 0; i < cnt; i++)
{
int a = edges[i].a;
int b = edges[i].b;
if (pos[a] > pos[b])
{
int tmp = a;
a = b;
b = tmp;
// a ^= b;
// b ^= a;
// a ^= b;
}
out.write(a + " " + b + "\n");
}
}
out.flush();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】