Simple tree DP
I had been RE this question yesterday, and finally wrote the stack with the help of my teammates.
Today, I read the code of yesterday and found that I did write it. In every dfs, I had to open a 10000 array, which is not so strange.
The Code capability is too scum. Continue to cheer!
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <algorithm>
# Include <cmath>
# Include <stack>
# Include <queue>
# Include <vector>
# Include <map>
# Include <ctime>
# Include <set>
# Include <string>
# Define N 20010
Using namespace std;
Struct Edge {
Int v, next;
} Edge [N * 2];
Int head [N];
Int n, cnt;
Int dp [N] [2];
Void init (){
Memset (head,-1, sizeof (head ));
Memset (dp, 0, sizeof (dp ));
Cnt = 0;
}
Void addedge (int u, int v ){
Edge [cnt]. v = v;
Edge [cnt]. next = head [u];
Head [u] = cnt ++;
Edge [cnt]. v = u;
Edge [cnt]. next = head [v];
Head [v] = cnt ++;
}
Void dfs (int u, int fa ){
Int sum = 0;
Int ans1 = 0, ans2 = 0;
Int a [2], j = 0;
A [0] = a [1] = 1000000000;
For (int I = head [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v;
If (v = fa) continue;
Sum ++;
Dfs (v, u );
Ans1 + = dp [v] [0];
Ans2 + = dp [v] [1];
If (a [0]> dp [v] [0]-dp [v] [1]) {
A [1] = a [0];
A [0] = dp [v] [0]-dp [v] [1];
}
Else if (a [1]> dp [v] [0]-dp [v] [1]) a [1] = dp [v] [0]-dp [v] [1];
}
If (sum = 0 ){
Dp [u] [0] = 0;
Dp [u] [1] = 100;
Return;
}
Dp [u] [0] = ans2;
Dp [u] [0] = min (dp [u] [0], ans1 + 500); // all cover
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + 100); // cover 1
If (sum> 1)
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + a [1] + 175); // cover 2
If (fa =-1) return;
Dp [u] [1] = ans2 + 100;
Dp [u] [1] = min (dp [u] [1], ans1 + 500); // all cover
Dp [u] [1] = min (dp [u] [1], ans2 + a [0] + 175 );
}
Int main (){
Int t, T, u, v, I;
Scanf ("% d", & T );
For (t = 1; t <= T; t ++ ){
Scanf ("% d", & n );
Init ();
For (I = 0; I <n-1; I ++ ){
Scanf ("% d", & u, & v );
Addedge (u, v );
}
Dfs (0,-1 );
Printf ("$ % d \ n", dp [0] [0]);
}
Return 0;
}
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <algorithm>
# Include <cmath>
# Include <stack>
# Include <queue>
# Include <vector>
# Include <map>
# Include <ctime>
# Include <set>
# Include <string>
# Define N 20010
Using namespace std;
Struct Edge {
Int v, next;
} Edge [N * 2];
Int head [N];
Int n, cnt;
Int dp [N] [2];
Void init (){
Memset (head,-1, sizeof (head ));
Memset (dp, 0, sizeof (dp ));
Cnt = 0;
}
Void addedge (int u, int v ){
Edge [cnt]. v = v;
Edge [cnt]. next = head [u];
Head [u] = cnt ++;
Edge [cnt]. v = u;
Edge [cnt]. next = head [v];
Head [v] = cnt ++;
}
Void dfs (int u, int fa ){
Int sum = 0;
Int ans1 = 0, ans2 = 0;
Int a [2], j = 0;
A [0] = a [1] = 1000000000;
For (int I = head [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v;
If (v = fa) continue;
Sum ++;
Dfs (v, u );
Ans1 + = dp [v] [0];
Ans2 + = dp [v] [1];
If (a [0]> dp [v] [0]-dp [v] [1]) {
A [1] = a [0];
A [0] = dp [v] [0]-dp [v] [1];
}
Else if (a [1]> dp [v] [0]-dp [v] [1]) a [1] = dp [v] [0]-dp [v] [1];
}
If (sum = 0 ){
Dp [u] [0] = 0;
Dp [u] [1] = 100;
Return;
}
Dp [u] [0] = ans2;
Dp [u] [0] = min (dp [u] [0], ans1 + 500); // all cover
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + 100); // cover 1
If (sum> 1)
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + a [1] + 175); // cover 2
If (fa =-1) return;
Dp [u] [1] = ans2 + 100;
Dp [u] [1] = min (dp [u] [1], ans1 + 500); // all cover
Dp [u] [1] = min (dp [u] [1], ans2 + a [0] + 175 );
}
Int main (){
Int t, T, u, v, I;
Scanf ("% d", & T );
For (t = 1; t <= T; t ++ ){
Scanf ("% d", & n );
Init ();
For (I = 0; I <n-1; I ++ ){
Scanf ("% d", & u, & v );
Addedge (u, v );
}
Dfs (0,-1 );
Printf ("$ % d \ n", dp [0] [0]);
}
Return 0;
}
Handwritten stack version
[Cpp]
// # Pragma comment (linker, "/STACK: 1024000000,1024000000 ")
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <stack>
# Define N 100010
Using namespace std;
Struct Edge {
Int v, next;
} Edge [N * 2];
Int head [N];
Int n, cnt;
Int dp [N] [2];
Void init (){
Memset (head,-1, sizeof (head ));
Memset (dp, 0, sizeof (dp ));
Cnt = 0;
}
Void addedge (int u, int v ){
Edge [cnt]. v = v;
Edge [cnt]. next = head [u];
Head [u] = cnt ++;
Edge [cnt]. v = u;
Edge [cnt]. next = head [v];
Head [v] = cnt ++;
}
Void dfs (){
Stack <pair <int, int> sta;
Sta. push (make_pair (0,-1 ));//*******
Bool vis [N];
Memset (vis, 0, sizeof (vis ));
While (! Sta. empty ()){//*******
Int u = sta. top (). first, fa = sta. top (). second ;//*******
If (vis [u] = 0 ){//*******
For (int I = head [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v;
If (v = fa) continue;
Sta. push (make_pair (v, u ));//*******
}
Vis [u] = 1 ;//*******
}
If (u! = Sta. top (). first )//*******
Continue;
Sta. pop ();//*******
Int sum = 0;
Int ans1 = 0, ans2 = 0;
For (int I = head [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v;
If (v = fa) continue;
Sum ++;
Ans1 + = dp [v] [0];
Ans2 + = dp [v] [1];
}
If (sum = 0 ){
Dp [u] [0] = 0;
Dp [u] [1] = 100;
Continue;
}
Dp [u] [0] = ans2;
If (sum = 1) dp [u] [0] = min (dp [u] [0], ans1 + 100 );
Else if (sum = 2) dp [u] [0] = min (dp [u] [0], ans1 + 175 );
Else dp [u] [0] = min (dp [u] [0], ans1 + 500); // all cover
Int a [N], j = 0;
If (sum> 1 ){
For (int I = head [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v;
If (v = fa) continue;
A [j ++] = dp [v] [0]-dp [v] [1];
}
Sort (a, a + j );
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + 100); // cover 1
If (sum> 2)
Dp [u] [0] = min (dp [u] [0], ans2 + a [0] + a [1] + 175); // cover 2
}
If (fa =-1) continue;
Dp [u] [1] = ans2 + 100;
If (sum = 1) dp [u] [1] = min (dp [u] [1], ans1 + 175 );
Else dp [u] [1] = min (dp [u] [1], ans1 + 500); // all cover
If (sum> 1 ){
Dp [u] [1] = min (dp [u] [1], ans2 + a [0] + 175 );
}
}
}
Int main (){
Int t, T, u, v, I;
Scanf ("% d", & T );
For (t = 1; t <= T; t ++ ){
Scanf ("% d", & n );
Init ();
For (I = 0; I <n-1; I ++ ){
Scanf ("% d", & u, & v );
Addedge (u, v );
}
Dfs ();
Printf ("$ % d \ n", dp [0] [0]);
}
Return 0;
}