题解:P3542 [POI 2012] PEN-Salaries
huangenning · · 题解
题目思路
自己造几棵树后可发现,每个结点都有最大可能权值。这个最大可能权值取决于其父亲的权值以及其它点是否占用某些权值。设第
有了这个思路后,我们可以先做一次从根部开始的 dfs 求所有
丑陋代码
#include<iostream>
#include<cstdio>
using namespace std;
const int NR=1000001;
bool f[NR];
int cnt,p[NR],z[NR],r[NR],s[NR],hed[NR],nxt[2*NR],to[2*NR];
void ad(int u,int v)
{
cnt++;
to[cnt]=v;
nxt[cnt]=hed[u];
hed[u]=cnt;
return;
}
void dfs(int x)
{
if(z[x]) r[x]=z[x];
else
{
r[x]=r[p[x]]-1;
while(f[r[x]]) r[x]--;
}
s[r[x]]++;
int i;
for(i=hed[x];i;i=nxt[i]) dfs(to[i]);
return;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n,i,fa;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>p[i]>>z[i];
if(p[i]==i)
{
z[i]=n;
fa=i;
}
else ad(p[i],i);
f[z[i]]=true;
}
dfs(fa);
for(i=1;i<=n;i++) s[i]+=s[i-1];
for(i=1;i<=n;i++)
if(!z[i] && s[r[i]]-s[r[i]-1]==1 && s[r[i]]==r[i]) z[i]=r[i];
for(i=1;i<=n;i++) cout<<z[i]<<endl;
return 0;
}
注意事项
1、题目未说明,所以可能存在所有点输入的
2、输入量较大,若不进行输入优化,会 TLE 掉一个测试点。