首先,建出来的是无向图,因为a看不上b他们一定不会一起被选出。。。

然后,n个点n条边,形成的是环套树森林

于是有个奇技淫巧的做法,先dfs一遍找到环上的两个点,然后拆掉那条边,记下来边的两端x, y两个节点

强制x为根且x不选做树形动规,然后强制y为根且y不选再做一遍树形动规,两次的最大值加入答案

注意写法,我记录了father就找不到二元环的情况了QAQQQ,WA到死。。。要记录来的那条边

 

 1 /**************************************************************
 2     Problem: 1040
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:1992 ms
 7     Memory:51724 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12  
13 using namespace std;
14 const int N = 1e6 + 5;
15  
16 struct edge {
17     int next, to, f;
18     edge() {}
19     edge(int _n, int _t, int _f = 1) : next(_n), to(_t), f(_f) {}
20 } e[N << 1];
21  
22 int n, rt1, rt2;
23 int first[N], tot = 1;
24 int v[N], vis[N];
25 long long f[N][2], ans;
26  
27 inline int read() {
28     int x = 0;
29     char ch = getchar();
30     while (ch < '0' || '9' < ch)
31         ch = getchar();
32     while ('0' <= ch && ch <= '9') {
33         x = x * 10 + ch - '0';
34         ch = getchar();
35     }
36     return x;
37 }
38  
39 inline void Add_Edges(int x, int y) {
40     e[++tot] = edge(first[x], y), first[x] = tot;
41     e[++tot] = edge(first[y], x), first[y] = tot;
42 }
43  
44 #define y e[x].to
45 void dfs(int p, int from) {
46     int x;
47     vis[p] = 1;
48     for (x = first[p]; x; x = e[x].next) 
49         if (!vis[y]) dfs(y, x);
50         else if ((from ^ 1) != x && !rt1)
51             rt1 = p, rt2 = y, e[x].f = e[x ^ 1].f = 0;
52 }
53  
54 void dp(int p, int t) {
55     int x;
56     vis[p] = t;
57     f[p][0] = 0, f[p][1] = v[p];
58     for (x = first[p]; x; x = e[x].next)
59         if (vis[y] != t && e[x].f) {
60             dp(y, t);
61             f[p][0] += max(f[y][0], f[y][1]);
62             f[p][1] += f[y][0];
63         }
64 }
65 #undef y
66  
67 int main() {
68     int i;
69     long long tmp;
70     n = read();
71     for (i = 1; i <= n; ++i)
72         v[i] = read(), Add_Edges(read(), i);
73     for (i = 1; i <= n; ++i)
74         if (!vis[i]) {
75             rt1 = rt2 = 0;
76             dfs(i, 0);
77             dp(rt1, 2), tmp = f[rt1][0];
78             dp(rt2, 3), ans += max(tmp, f[rt2][0]);
79         }
80     printf("%lld\n", ans);
81     return 0;
82 }
View Code

 

posted on 2015-03-17 19:38  Xs酱~  阅读(458)  评论(0编辑  收藏  举报