1 条题解
-
0
此题等同于给定一个基环树森林,求其中最大环。
因为是内向树,一棵树内的强连通分量只有那个环,所以跑出所有强连通分量后取 就可以了
当然也可以用拓扑排序写,写好了还要 划分每个环,
所以我懒得写了#include <cstdio> #include <iostream> using namespace std; const int M = 200005; struct edge{ int to, nxt; }e[M << 1]; int head[M], cnt1, ans = M << 2; void link(int u, int v){ e[++cnt1].to = v; e[cnt1].nxt = head[u]; head[u] = cnt1; } int n, m, u, v, dfn[M], low[M], cnt, st[M], top, c[M], siz[M], cc; bool in[M]; void tarjan(int u){ dfn[u] = low[u] = ++cnt; st[++top] = u; in[u] = 1; for(int i = head[u]; i; i = e[i].nxt){ int v = e[i].to; if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]); else if(in[v]) low[u] = min(low[u], dfn[v]); } if(low[u] != dfn[u]) return; ++cc; do{ c[st[top]] = cc; siz[cc]++; in[st[top]] = 0; } while(st[top--] != u); } int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++) {scanf("%d", &v); link(i, v);} for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= cc; i++) if(siz[i] > 1) ans = min(ans, siz[i]); printf("%d\n", ans); }
- 1
信息
- ID
- 1026
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 15
- 已通过
- 14
- 上传者