与大多数人做法一样,都是每个点排一遍序 Θ(nlogn),并且也没有特意卡常(除了加了 谁都会加的 快读快输),但是就是比别人快,冲到了最优解第三,用时大概是别人一半(280ms/500ms+)。
是因为评测波动吗 /kel
附代码:
#include <cstdio>
#include <algorithm>
using namespace std;
void chkmax(int& a,int b) { if(b>a) a=b; }
int getint()
{
char ch;
while((ch=getchar()) < '!') ;
int x = ch^'0';
while((ch=getchar()) > '!') x = (x*10)+(ch^'0');
return x;
}
void putint(int x)
{
if(x/10) putint(x/10);
putchar((x%10)^'0');
}
int beg[100010];
int ed[100010];
int nxt[100010];
int top;
void addedge(int a,int b)
{
++top;
ed[top] = b;
nxt[top] = beg[a];
beg[a] = top;
}
int wi[100010];
int dp[100010];
int tmp[100010];
bool cmp(int a,int b)
{
return max(wi[a]+dp[b],dp[a]) < max(wi[b]+dp[a],dp[b]);
}
void tdp(int x)
{
for(int p=beg[x]; p; p=nxt[p])
{
tdp(ed[p]);
}
int ttop = 0;
for(int p=beg[x]; p; p=nxt[p])
{
tmp[++ttop] = ed[p];
}
sort(tmp+1,tmp+1+ttop,cmp);
dp[x] = 0;
int swi = 0;
for(int i=1; i<=ttop; ++i)
{
chkmax(dp[x],swi+dp[tmp[i]]);
swi += wi[tmp[i]];
}
chkmax(dp[x], swi+wi[x]);
}
int main()
{
const int n = getint();
for(int i=2; i<=n; ++i)
{
addedge(getint(),i);
}
for(int i=1; i<=n; ++i)
{
wi[i] = getint();
}
tdp(1);
for(int i=1; i<=n; ++i)
{
putint(dp[i]);
putchar(' ');
}
putchar('\n');
}