[USACO08DEC]在農場萬聖節Trick or Treat on the Farm【Tarja縮點+dfs】
阿新 • • 發佈:2019-04-01
|| ret print add elong space std usaco ext
(翻譯來自洛谷)
題目描述
每年,在威斯康星州,奶牛們都會穿上衣服,收集農夫約翰在N(1<=N<=100,000)個牛棚隔間中留下的糖果,以此來慶祝美國秋天的萬聖節。
由於牛棚不太大,FJ通過指定奶牛必須遵循的穿越路線來確保奶牛的樂趣。為了實現這個讓奶牛在牛棚裏來回穿梭的方案,FJ在第i號隔間上張貼了一個“下一個隔間”Next_i(1<=Next_i<=N),告訴奶牛要去的下一個隔間;這樣,為了收集它們的糖果,奶牛就會在牛棚裏來回穿梭了。
FJ命令奶牛i應該從i號隔間開始收集糖果。如果一只奶牛回到某一個她已經去過的隔間,她就會停止收集糖果。
在被迫停止收集糖果之前,計算一下每頭奶牛要前往的隔間數(包含起點)。
分析
比較容易可以想到,如果一個奶牛位於一個環中,那麽它的答案就是這個環的大小。
如果一個奶牛不在一個環中,那麽答案就是到它最近的環的距離再加上環的大小。
代碼
#include <bits/stdc++.h> #define ll long long #define ms(a, b) memset(a, b, sizeof(a)) #define inf 0x3f3f3f3f #define db double #define N 100005 using namespace std; template <typename T> inline void read(T &x) { x = 0; T fl = 1; char ch = 0; for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1; for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48); x *= fl; } struct edge { int to, nt; }E[N]; int H[N], dfn[N], vis[N], S[N], nxt[N], belong[N], low[N], ans[N], sum[N]; int scc, cnt, dfn_tot, top, n; void add_edge(int u, int v) { E[++ cnt] = (edge){v, H[u]}; H[u] = cnt; } void tarjan(int u) { vis[u] = 1; low[u] = dfn[u] = ++ dfn_tot; S[top ++] = u; for (int e = H[u]; e; e = E[e].nt) { int v = E[e].to; if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]); else if (vis[v]) low[u] = min(low[u], low[v]); } int j; if (dfn[u] == low[u]) { scc ++; do { j = S[-- top]; belong[j] = scc; vis[j] = 0; } while (u != j); } } void dfs(int u, int nt, int dis) { if (ans[nt] != 0) { ans[u] = ans[nt] + dis; return; } else dfs(u, nxt[nt], dis + 1); } int main() { read(n); for (int i = 1; i <= n; i ++) { read(nxt[i]); add_edge(i, nxt[i]); if (nxt[i] == i) ans[i] = 1; } for (int i = 1; i <= n; i ++) if (!dfn[i]) tarjan(i); for (int i = 1; i <= n; i ++) sum[belong[i]] ++; for (int i = 1; i <= n; i ++) if (sum[belong[i]] != 1) ans[i] = sum[belong[i]]; for (int i = 1; i <= n; i ++) if (ans[i] == 0) dfs(i, nxt[i], 1); for (int i = 1; i <= n; i ++) printf("%d\n", ans[i]); return 0; }
[USACO08DEC]在農場萬聖節Trick or Treat on the Farm【Tarja縮點+dfs】