本题的图应该是若干由单一有向简单环构成的连通块,为什么建有向图dfs跑连通块就错,无向图dfs跑连通块就对?
30:
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int n, head[N], cnt, ans;
bool vis[N];
struct Edge {
int to, nxt;
} edges[N << 1];
void add_edge(int from, int to) {
edges[++ cnt] = (Edge){to, head[from]};
head[from] = cnt;
}
void dfs(int x) {
vis[x] = 1;
for (int i = head[x]; i; i = edges[i].nxt) {
int y = edges[i].to;
if (! vis[y]) dfs(y);
}
}
int main() {
scanf("%d", &n);
for (int i = 1, a; i <= n; i ++) scanf("%d", &a), add_edge(a, i);
for (int i = 1; i <= n; i ++) if (! vis[i]) dfs(i), ans ++;
printf("%d", ans);
return 0;
}
AC:
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int n, head[N], cnt, ans;
bool vis[N];
struct Edge {
int to, nxt;
} edges[N << 1];
void add_edge(int from, int to) {
edges[++ cnt] = (Edge){to, head[from]};
head[from] = cnt;
}
void dfs(int x) {
vis[x] = 1;
for (int i = head[x]; i; i = edges[i].nxt) {
int y = edges[i].to;
if (! vis[y]) dfs(y);
}
}
int main() {
scanf("%d", &n);
for (int i = 1, a; i <= n; i ++) scanf("%d", &a), add_edge(a, i), add_edge(i, a);
for (int i = 1; i <= n; i ++) if (! vis[i]) dfs(i), ans ++;
printf("%d", ans);
return 0;
}