day 2 下午 骑士 基环树+树形DP
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=2e6+10; 8 long long dp[maxn][2]; 9 long long w[maxn]; 10 11 struct node 12 { 13 long long to,next,value; 14 }way[maxn]; 15 long long tmp; 16 long long tot; 17 long long n,x; 18 long long head[maxn]; 19 bool vis[maxn]; 20 long long root; 21 long long father; 22 long long ans1,ans; 23 int read() 24 { 25 int flag = 1; 26 char c = getchar(); 27 while ((!isdigit(c)) && c != '-') c = getchar(); 28 if (c == '-') flag = -1, c = getchar(); 29 int init = c & 15; 30 while (isdigit(c = getchar())) init = (init << 3) + (init << 1) + (c & 15); 31 return init * flag; 32 } 33 void add(long long x,long long y,long long w) 34 { 35 way[++tot].next=head[x]; 36 way[tot].to=y; 37 way[tot].value=w; 38 head[x]=tot; 39 } 40 void dfs(long long x,long long fa) 41 { 42 vis[x]=1; 43 for(int i=head[x];i;i=way[i].next) 44 { 45 long long to=way[i].to; 46 if(to==fa) 47 { 48 continue; 49 } 50 if(vis[to]) 51 { 52 root=to; 53 father=x; 54 tmp=way[i].value; 55 } 56 else 57 { 58 dfs(to,x); 59 } 60 } 61 } 62 void shu_dp(long long x,long long fa) 63 { 64 dp[x][0]=0; 65 dp[x][1]=w[x]; 66 for(int i=head[x];i;i=way[i].next) 67 { 68 long long to=way[i].to; 69 if(way[i].value==tmp||to==fa) 70 { 71 continue; 72 } 73 shu_dp(to,x); 74 dp[x][0]+=max(dp[to][0],dp[to][1]); 75 dp[x][1]+=dp[to][0]; 76 } 77 } 78 int main() 79 { 80 n=read(); 81 for(int i=1;i<=n;i++) 82 { 83 w[i]=read(); 84 x=read(); 85 add(i,x,i); 86 add(x,i,i); 87 } 88 for(int i=1;i<=n;i++) 89 { 90 if(!vis[i]) 91 { 92 dfs(i,0); 93 shu_dp(root,0); 94 ans1=dp[root][0]; 95 shu_dp(father,0); 96 long long ans2; 97 ans2=dp[father][0]; 98 ans1=max(ans1,ans2); 99 ans+=ans1; 100 } 101 } 102 printf("%lld\n",ans); 103 return 0; 104 }