1. 题意描述
2. 输入样例
3. 思路
按照题意模拟,然后注意longlong,和模拟的过程。
其实可以得出一些技巧,比如你可以先把伪代码写出来,然后再进行变成,这样可以理解清楚思路,加快速度。
4. 代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e3+10;
int w[N];
int fa[N];
ll sze[N];
int sons[N];
ll w_min = N+1,w_M = LONG_MAX;
vector<int> son[N];
int vis[N];
int cnt;
ll sum;
void dfs(int root)
{
if (vis[root] == 0) {sze[root] = 0;sons[root] = 0;return;}
sze[root] = w[root];
sons[root] = 1;
sum += w[root];
for (int i = 0;i < son[root].size();i ++) {
dfs(son[root][i]);
sze[root] += sze[son[root][i]];
sons[root] += sons[son[root][i]];
}
}
void dfs2(int root)
{
if (vis[root] == 0) return;
ll tmp = abs(sum - sze[root]*2);
// cout<<root<<":"<<tmp<<endl;
if (tmp < w_M) {
w_M = tmp;w_min = root;
}
if (tmp == w_M&&w_min>root)
w_min = root;
for (int i = 0;i < son[root].size();i ++) {
dfs2(son[root][i]);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
freopen("aout.txt","w",stdout);
#endif
int n,m;cin>>n>>m;
for (int i = 1;i <= n;i ++) cin>>w[i];
for (int i = 1;i < n;i ++)
{
int x;cin>>x;
fa[i+1] = x;
son[x].push_back(i+1);
}
while (m --) {
int x;cin>>x;
int root = 1;
for (int i = 1;i <= n;i ++) vis[i] = 1;
cnt = n;
while (cnt > 1) {
sum = 0,w_M = LONG_MAX,w_min = N+1;
dfs(root);
dfs2(root);
int tx = x;
cout<<w_min<<" ";
while (tx != root&&tx != w_min) tx = fa[tx];
if (tx == root) {
cnt -= sons[w_min];root = root;
vis[w_min] = 0;
} else {
root = w_min;
cnt = sons[w_min];
}
}cout<<endl;
}
}