本解法採用 遞歸 DFS 而非並查集,邏輯更直觀:
No#include <iostream>
#include <cstring>
#include <vector>
const int MAXN = 110000;
int head[MAXN], vis[MAXN], sensor[MAXN];
struct Edge { int to, next; } edges[MAXN*4];
int ecnt;
void addEdge(int u, int v) {
edges[ecnt] = {v, head[u]}; head[u] = ecnt++;
edges[ecnt] = {u, head[v]}; head[v] = ecnt++;
}
void dfs(int u) {
vis[u] = 1;
for (int e = head[u]; ~e; e = edges[e].next) {
int v = edges[e].to;
if (vis[v]) continue;
if (sensor[v]) { vis[v] = 1; continue; } // 遇到未激活觸發器停止
dfs(v);
}
}
void dfsAll(int u, int& cnt) {
vis[u] = 1; ++cnt;
for (int e = head[u]; ~e; e = edges[e].next) {
int v = edges[e].to;
if (!vis[v]) dfsAll(v, cnt);
}
}
int main() {
int T; scanf("%d", &T);
while (T--) {
memset(head, -1, sizeof head);
memset(vis, 0, sizeof vis);
memset(sensor, 0, sizeof sensor);
ecnt = 0;
int n, m, k; scanf("%d%d%d", &n, &m, &k);
for (int i=0, x; i
| 指標 | DFS 遞歸 | 並查集 + BFS |
|---|---|---|
| 時間 | O(n+m) | O((n+m) α(n)) |
| 棧深度 | O(n) 風險棧溢出 | O(1) 額外空間 |
| 代碼簡潔度 | 高 | 中 |
| 適用場景 | n ≤ 10⁵, 深度可控 | 通用、無棧溢出風險 |
sensor[v] 為 1 表示「尚未激活的觸發器」,DFS 遇到即標記訪問但不繼續深入vis[]