Title Description Description
The Knights of Z are a powerful organization that brings together elites from all over the world. They maxi and punish evil and Good, and are praised by all sectors of the community.
A terrible thing has happened recently, and the evil Y countries have launched a war of aggression against Z-states. The war stretches for 500 miles, and the Z-nation, who has been comfortably in peace for hundreds of years, can withstand the forces of the nations of Y. So people pinned all their hopes on the Knights, as if expecting the birth of a true dragon, leading Justice to defeat evil.
The Knights were certainly capable of defeating the forces of evil, but the Knights often had some contradictions with each other. Every knight has and only one of his own most hated Knight (not himself), he is absolutely not with his most dislike of the people to the expedition together.
War stretches, the people misery, organized a Knight Corps to join the Battle of urgency! The king has given you a formidable task, electing a Knight Corps from all the knights, so that there are no contradictory members of the Legion (there is no knight in the case of the Knights with whom he hates the most), and that the Knight Corps is the most capable of fighting.
In order to describe the combat effectiveness, we numbered the Knights according to 1 to N, giving each knight an estimate of the combat effectiveness of a legion that is the sum of the fighting power of all knights.
Enter a description input Description
The first line contains a positive integer n, which describes the number of knights.
The next n lines, two positive integers per line, describe in order the combat effectiveness of each knight and the knight he hates most.
Outputs description Output Description
Should contain a line containing an integer representing the combat effectiveness of your chosen Knight Corps.
Sample input to sample
3
10 2
20 3
30 1
Sample output Sample Outputs
30
Data Size & Hint
For 30% of test data, meet n≤10;
For 60% of test data, meet n≤100;
For 80% of test data, N≤10 000 is satisfied.
For 100% of the test data, meet N≤1 000 000, each knight's combat effectiveness is not greater than 1 000 000 positive integer.
Exercises
It can be found that if you press the two people who hate each other, it is a ring-set tree forest.
For each ring set of trees
We can first DP all the outward trees;
DP[I][1] The maximum value of the I node for the subtree with the I node as the root.
DP[I][0] The maximum value of the I node is not selected for subtrees with the I node as root.
V[i] is the combat power of node I.
The DP equation is:
Dp[i][1]=sum (Dp[j][0]) (j is a sub-node of i);
Dp[i][0]=sum (Max (dp[j][1],dp[j][0])) +v[i]; (j is a child of I);
Then choose a location as the beginning of the chain to break the loop for DP;
F[i][0] To select the 1th point, do not select the maximum value of the first point.
F[I][1] To select the 1th point, select the maximum value of the first point.
F[I][2] To select the 1th point, the maximum value of the first point is selected.
F[I][3] The 1th point is not selected, the maximum value of the I point is not selected.
The c array holds the broken chain, c[0] is the length of the chain.
The DP equation is:
F[i][0]=max (F[i-1][0],f[i-1][1]) +dp[c[i]][0];
F[I][1]=F[I-1][0]+DP[C[I]][1];
F[I][2]=F[I-1][3]+DP[C[I]][1];
F[i][3]=max (f[i-1][3],f[i-1][2]) +dp[c[i]][0];
Initial value:
F[1][1]=DP[C[1]][1];
F[1][2]=F[1][3]=F[1][0]=DP[C[1]][0];
There is one last question.
How do we find all the ring sets of trees.
The specific method is to set each knight's dislike to his father. And from his father to his side. Note that you can only have a forward edge.
Then choose a person and move on to his father. This finally always turns to a ring.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace STD;structuse{intL,r;} b[1000001];intpoint[1000001],t,next[1000001],n,a,tot,fa[1000001],k,son[1000001],now,c[1000001];Long Longdp[1000001][3],f[1000001][5],ans,v[1000001],temp;BOOLmark[1000001];voidAddintXintY) {next[++tot]=point[x];p oint[x]=tot; B[tot].l=x;b[tot].r=y;}voidInit () {scanf("%d", &n); for(intI=1; i<=n;i++) {scanf("%lld%d", &v[i],&a); Fa[i]=a; Add (a,i); }}voidTREEDP (intx) {dp[x][1]=V[X]; mark[x]=true; for(intI=point[x];i;i=next[i]) {TREEDP (B[I].R); dp[x][0]+=max (dp[b[i].r][1],dp[b[i].r][0]); dp[x][1]+=dp[b[i].r][0]; }}voidLASTDP () {f[1][1]=dp[c[1]][1]; f[1][2]=f[1][3]=f[1][0]=dp[c[1]][0]; for(intI=2; i<=c[0];i++) {f[i][0]=max (f[i-1][0],f[i-1][1]) +dp[c[i]][0]; f[i][1]=f[i-1][0]+dp[c[i]][1]; f[i][2]=f[i-1][3]+dp[c[i]][1]; f[i][3]=max (f[i-1][3],f[i-1][2]) +dp[c[i]][0]; } Temp=max (f[c[0]][0],max (f[c[0]][2],f[c[0]][3]));}voidSolve () { for(intI=1; i<=n;i++) {if(Mark[i])Continue; K=i; c[0]=0; while(!mark[k]) {mark[k]=true; K=FA[K]; Son[fa[k]]=k; } now=k; while(1) {T=point[k]; dp[k][1]=V[K]; while(t>0) {if(B[t].r!=son[k]) {TREEDP (B[T].R); dp[k][0]+=max (dp[b[t].r][1],dp[b[t].r][0]); dp[k][1]+=dp[b[t].r][0]; } T=next[t]; } c[++c[0]]=k; K=FA[K];if(K==now) Break; } LASTDP (); Ans+=temp; }printf("%lld", ans);}intMain () {init (); Solve ();return 0;}
"bzoj1040" "zjoi2008" Knight (tree-shaped DP)