codeforces round 530 div2
tags:
- dfs
- codeforces
- acm
- ACM
A,B,C:都很简单,不说了。
D:一棵树,给出树的结构,以及从树根到某个深度为偶数的节点的路径和,问能否构造一种所有节点点权和最小的树,输出最小点权和。
思路:
容易知道,如果想要点权和最小,那么尽可能让靠近树根的点承担更多的点权。
具体做法是,bfs,对于每个节点u,取其儿子中最小的S值求节点u的信息。
比赛的时候wa16…最后发现是答案要用long long存…因为单个路径和是<=1E9的。。多个加起来会超过int… 长时间不打连这种常见的坑都不敏感了啊。。。
1#include <bits/stdc++.h>
2#define PB push_back
3#define fst first
4#define sec second
5#define lson l,m,rt<<1
6#define rson m+1,r,rt<<1|1
7#define ms(a,x) memset(a,x,sizeof(a))
8typedef long long LL;
9#define pi pair < int ,int >
10#define MP make_pair
11
12using namespace std;
13const double eps = 1E-8;
14const int dx4[4]={1,0,0,-1};
15const int dy4[4]={0,-1,1,0};
16const int inf = 0x3f3f3f3f;
17const int N=1E5+7;
18int n;
19vector<int>edge[N];
20int s[N];
21int d[N];
22bool vis[N];
23int a[N];
24// void dfs(int u,int dep)
25// {
26// int siz = edge[u].size();
27// for (auto v: edge[u])
28// {
29// dfs(v,dep+1);
30// }
31// }
32int bfs()
33{
34 ms(d,-1);
35 ms(vis,false);
36 queue<int>Q;
37 Q.push(1); //root
38 vis[1] = true;
39 d[1] = s[1];
40 while (!Q.empty())
41 {
42 int u = Q.front();Q.pop();
43 // cout<<"u:"<<u<<" "<<Q.size()<<endl;
44 int min_sum_in_leaf = inf;
45 bool even = false;
46 // cout<<"v seq:";
47 for ( auto v: edge[u])
48 {
49 // cout<<v<<" s[v]:"<<s[v]<<" ";
50 if (s[v]==-1)
51 {
52 Q.push(v);
53 d[v] = d[u];
54 even = true;
55 }
56 if (s[v]!=-1) min_sum_in_leaf = min(min_sum_in_leaf,s[v]);
57 }
58 cout<<endl;
59 if (even) continue;
60 // cout<<"min_sum_in_leaf:"<<min_sum_in_leaf<<endl;
61 // cout<<"u:"<<u<<" d[u]:"<<d[u]<<endl;
62 if (d[u]>min_sum_in_leaf) return -1; //不可能
63 if (min_sum_in_leaf==inf)
64 {
65 // a[u] =
66 continue;
67 }
68 a[u] = min_sum_in_leaf - d[u];
69 d[u] = min_sum_in_leaf;
70 for ( auto v: edge[u])
71 {
72 a[v] = s[v] - d[u];
73 d[v] = s[v];
74 // cout<<"v:"<<v<<" a[v]:"<<a[v]<<" d[v]:"<<d[v]<<endl;
75 Q.push(v);
76 }
77 }
78 return 0;
79}
80int main()
81{
82 #ifndef ONLINE_JUDGE
83 freopen("./in.txt","r",stdin);
84 #endif
85
86 cin>>n;
87 for ( int i = 2 ; i <= n ; i++)
88 {
89 int x;
90 cin>>x;
91 edge[x].push_back(i);
92 }
93 for ( int i = 1 ; i <= n ; i++) cin>>s[i];
94// for ( int i = 1 ;i <= n ; i++) cout<<"s[i]:"<<s[i]<<endl;
95 ms(a,0);
96 a[1] = s[1];
97 LL ans = bfs();
98 if (ans==-1)
99 {
100 puts("-1");
101
102 }
103 else
104 {
105 for ( int i = 1 ; i <= n ; i++)
106 {
107 // cout<<i<<":"<<a[i]<<" d:"<<d[i]<<" s:"<<s[i]<<endl;
108 ans = ans + a[i];
109 }
110 cout<<ans<<endl;
111 }
112
113
114
115
116
117 #ifndef ONLINE_JUDGE
118 fclose(stdin);
119 #endif
120 return 0;
121}