【BZOJ1589】[Usaco2008 Dec]Trick or Treat on the Farm 采集糖果【SCC】【基环外向树】【DP】【记忆化搜索】

来源:互联网 发布:易语言csol游戏源码 编辑:程序博客网 时间:2024/06/06 14:02

http://www.lydsy.com/JudgeOnline/problem.php?id=1589

首先这是一个基环外向树,先tarjan缩点变成DAG,然后跑dp就行了。


记忆化搜索写成了

if(dp[x]) return x;

一定是没睡好...


/* Footprints In The Blood Soaked Snow */#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100005;int n, dp[maxn], size[maxn], belong[maxn], next[maxn], to[maxn], dfn[maxn], low[maxn], clo, tot;bool ins[maxn];inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}int sta[maxn], top;inline void tarjan(int x) {dfn[x] = low[x] = ++clo;ins[sta[++top] = x] = 1;if(!dfn[next[x]]) tarjan(next[x]), low[x] = min(low[x], low[next[x]]);else if(ins[next[x]]) low[x] = min(low[x], dfn[next[x]]);if(low[x] == dfn[x]) {tot++;while(1) {int u = sta[top--];belong[u] = tot;size[tot]++;ins[u] = 0;if(u == x) break;}}}inline int dfs(int x) {if(dp[x]) return dp[x];dp[x] = size[x];if(to[x]) dp[x] += dfs(to[x]);return dp[x];}int main() {n = iread();for(int i = 1; i <= n; i++) next[i] = iread();for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i);for(int i = 1; i <= n; i++) if(belong[i] != belong[next[i]]) to[belong[i]] = belong[next[i]];for(int i = 1; i <= n; i++) printf("%d\n", dfs(belong[i]));return 0;}


0 0
原创粉丝点击