A directed graph has n vertices and n edges. Each vertex has only one outbound edge. A certain point has a belief value. If a certain point is obtained at the same time as its successor node, its belief value will change a value and ask how to obtain the point so that the total belief value is the largest.
Solution: Topology Sorting + tree DP. the figure of this question is very distinctive. I met it for the first time. The official question is that an octopus diagram is true. Because each vertex has only one outbound edge, one or more rings must exist, other points depend on these rings. This question is only AC after one day. The reason is that an int64 is written as an int, so sad...
For this question, my solution is to first process the tentacles of the octopus, that is, the edges that rely on the rings, and then process the rings one by one. The former is a common tree-like dp, because each vertex only has two states: build or not build. If dp [I] [0] is set, it indicates the maximum belief value obtained by point I without building nangu, dp [I] [1] indicates the maximum value of belief obtained by point I jianngu Hospital, in this case, you can use the dp [next] [0] = max (dp [I] [0], dp [I] [1]), dp [next] [1] = max (dp [I] [0], dp [I] [1]-g [I]), or you need to add a g [I] because at the same time, the School of nangu must subtract a certain value of faith. How is the transfer order achieved? I can't always find the leaves and update them again and again, right? Step by step update with Topology Sorting, until those rings, their inbound edge is never 0.
After processing the tentacles, we are about to start anatomy of the Octopus. Because it is a ring, we cannot simply transfer it as before, so that the status from point I to the end of point I will be very chaotic. To solve this problem, I think of a method to solve the problem on the Ring-split the ring. Split the ring into a chain from a point. This question is divided into two situations to enter the ring. When we encounter this point again, the transfer equation is the same as above in other cases.
Test data:
2
3-1 2
2-2 1
4
3-2 2
4-3 3
2-1 1
5-2 2
4
3 0 2
4 0 3
2 0 1
5 0 2
4
3-2 2
4-3 3
2-2 1
5-9 2
OutPut:
3
9
14
8
C producer code:
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Include <vector>
Using namespace std;
# Deprecision MAX 110000
# Define int64 long
# Define max (a, B) (a)> (B )? (A) (B ))
Struct node {
Int val, g, v;
} Arr [MAX];
Int st [MAX], top, cnt [MAX], tot; // used for topological sorting
Int mmap [MAX], n, flag [MAX]; // flag indicates whether the vertex is in the ring. dp [I] [0] indicates that the vertex is not created in I, and 1 indicates that the vertex is created in I.
Int64 dp [MAX] [2], power [MAX] [2], ans;
Void Initial (){
Ans = top = 0;
Memset (dp, 0, sizeof (dp ));
Memset (cnt, 0, sizeof (cnt ));
Memset (flag, 0, sizeof (flag ));
Memset (power, 0, sizeof (power ));
}
Void Debug_Input (){
// Printf ("top = % d \ n", tot );
For (int I = 1; I <= n; ++ I)
Printf ("power [% d] [0] = % d power [% d] [1] = % d \ n", I, power [I] [0], i, power [I] [1]);
}
Void ToooPooo (){
Int I, j, k, cur, next;
For (I = 1; I <= n; ++ I)
If (! Cnt [I]) st [++ top] = I;
While (top ){
Cur = st [top --];
Tot ++;
Flag [cur] = 1; // point in non-ring
Dp [cur] [1] + = arr [cur]. val;
Next = mmap [cur];
Dp [next] [0] + = max (dp [cur] [0], dp [cur] [1]);
Dp [next] [1] + = max (dp [cur] [0], dp [cur] [1] + arr [cur]. g );
Cnt [next] --;
If (cnt [next] = 0) st [++ top] = next;
}
}
Void Dfs (int s, int kind ){
Flag [s] = 1;
Int next = mmap [s];
Power [s] [1] + = arr [s]. val; // here, the temple is created regardless of the order followed by the increased belief value.
If (! Flag [next]) {
Power [next] [0] = dp [next] [0];
Power [next] [1] = dp [next] [1];
Power [next] [0] + = max (power [s] [0], power [s] [1]);
Power [next] [1] + = max (power [s] [0], power [s] [1] + arr [s]. g );
Dfs (next, kind );
}
Else {
If (kind = 0) power [next] [0] = max (power [s] [0], power [s] [1]);
Else power [next] [1] = max (power [s] [0], power [s] [1] + arr [s]. g );
}
If (kind = 0) flag [s] = 0;
}
Int main ()
{
Int I, j, k;
While (scanf ("% d", & n )! = EOF ){
Initial ();
For (I = 1; I <= n; ++ I ){
Scanf ("% d", & arr [I]. val, & arr [I]. g, & arr [I]. v );
Cnt [arr [I]. v] ++;
Mmap [I] = arr [I]. v;
}
ToooPooo ();
For (I = 1; I <= n; ++ I)
If (flag [I] = 0 ){
Int next = mmap [I];
Dp [I] [1] + = arr [I]. val;
Int64 temp = max (dp [I] [1], dp [I] [0]);
Power [I] [0] = dp [I] [0];
Power [I] [1] = dp [I] [1];
Power [next] [0] = dp [next] [0];
Power [next] [1] = dp [next] [1];
Power [next] [0] + = dp [I] [0];
Power [next] [1] + = dp [I] [0];
Flag [I] = 1;
Dfs (next, 0 );
Temp = max (temp, power [I] [0]);
Power [next] [0] = dp [next] [0];
Power [next] [1] = dp [next] [1];
Power [next] [0] + = dp [I] [1];
Power [next] [1] + = dp [I] [1] + arr [I]. g;
Flag [I] = 1;
Dfs (next, 1 );
Ans + = max (temp, power [I] [1]);
}
Printf ("% lld \ n", ans );
}
}
Author: woshi250hua