The main topic: give a graph of each point has a dependency node, select a node must select the node's dependency node, will get the weight of this node. Each point has a space, gives the total space limit, and asks how many weights can be obtained.
Idea: The point that appears in a ring is either select all or not, so you can shrink the point, then turn into a tree, and make a tree backpack on the tree.
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 2010using namespace Std; int Head[max],total;int Next[max],aim[max]; inline void Add (int x,int y) {next[++total] = head[x]; Aim[total] = y; HEAD[X] = total;} int Cost[max],val[max];int Father[max]; int cnt,all; int dfn[max],low[max],_clock;int Stack[max],top;bool In_stack[max];int changed[max],scc; void Tarjan (int x) {dfn[x] = low[x] = ++_clock; Stack[++top] = x; In_stack[x] = true; for (int i = head[x]; i; i = Next[i]) {if (!dfn[aim[i]]) Tarjan (Aim[i]), low[x] = min (low[x],low[aim[i]]); else if (In_stack[aim[i]]) low[x] = min (low[x],dfn[aim[i]]); } if (dfn[x] = = Low[x]) {scc++; int temp; do {temp = stack[top--]; In_stack[temp] = false; CHANGED[TEMP] = SCC; }while (temp! = x); }} struct graph{int head[max],total; int Next[max],aim[max]; Int_in[max],f[max][max]; int Cost[max],val[max]; void Add (int x,int y) {next[++total] = head[x]; Aim[total] = y; HEAD[X] = total; ++_in[y]; } void DP (int x) {for (int i = head[x]; i; i = Next[i]) {DP (aim[i]); for (int j = all-cost[x], j >= 0;--j) for (int k = 0; k <= J; ++k) f[x][j] = max ( F[X][J],F[X][K] + f[aim[i]][j-k]); } for (int i = all; i; i) {if (I >= cost[x]) f[x][i] = F[x][i-cost[x]] + val[x]; else f[x][i] = 0; }} int Getans () {memset (f,0,sizeof (f)); int S = 0; for (int i = 1; I <= SCC; ++i) if (!_in[i]) Add (s,i); DP (S); return F[s][all]; }}graph; int main () {cin >> cnt >> all; for (int i = 1; I <= cnt; ++i) scanf ("%d", &cost[i]); for (int i = 1; I <= cnt; ++i) scanf ("%d", &val[i]); for (int x,i = 1;i <= cnt; ++i) {scanf ("%d", &x); if (x) Add (x,i); } for (int i = 1; I <= cnt; ++i) if (!dfn[i]) Tarjan (i); for (int x = 1; x <= cnt, ++x) for (int i = head[x]; i; i = Next[i]) if (changed[x]! = Changed[aim[i]]) Graph. ADD (Changed[x],changed[aim[i]]); for (int i = 1; I <= cnt; ++i) {Graph.cost[changed[i]] + = cost[i]; Graph.val[changed[i]] + = val[i]; } cout << Graph. Getans () << Endl; return 0;}
Bzoj 2427 haoi 2010 Software Installation tarjan+ Tree DP