CF F
  • 板块学术版
  • 楼主LargeRice16pro
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/12/20 01:09
  • 上次更新2023/12/20 15:17:33
查看原帖
CF F
225100
LargeRice16pro楼主2023/12/20 01:09

我的思路是按层贪心。对于只有一个点的一层,如果它前面有奇数个数个点的层,它就有 1 贡献;反之如果前面有偶数个数个点的层,就多一个奇数个数的层,没有贡献。奇数和偶数层的贡献就是 个数/2 下取整。

感觉很对,求 hack。

#include<bits/stdc++.h>
// #pragma GCC optimize ("O2")
#define int long long
#define ldb long double 
#define For(i,a,b) for(i=a;i<=b;i++)
#define FOR(i,a,b) for(i=a;i>=b;i--)
#define pb push_back
using namespace std;
const int N=5e5+10;
int fa[N],cnt[N];
int n,m;
vector<int> p[N];
void dfs(int x,int y){
    cnt[y]++;
    for(auto u:p[x]){
        dfs(u,y+1);
    }
}
void solve(){
    int i;
    dfs(1,1);
    int ans=0;
    stack<int> s[2];
    For(i,1,n){
        if(cnt[i]==1){
            if(s[1].size()){
                auto num1=s[1].top();
                s[1].pop();
                num1--;
                if(num1) s[0].push(num1);
                ans++;
            }
            else if(s[0].size()){
                auto num0=s[0].top();
                s[0].pop();
                num0--;
                if(num0>1) s[1].push(num0);
            }
        }
        else if(cnt[i]%2) s[1].push(cnt[i]-2);
        else if(cnt[i]%2==0&&cnt[i]>2) s[0].push(cnt[i]-2);
        ans+=cnt[i]/2;
    }
    int len=s[1].size();
    // cout<<len<<'\n';
    cout<<ans+len/2<<'\n';
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t,i;
    cin>>t;
    while(t--){
        cin>>n;
        For(i,2,n) cin>>fa[i],p[fa[i]].pb(i);
        solve();
        For(i,1,n) p[i].clear();
        For(i,1,n) cnt[i]=0;
    }
    return 0;
}
2023/12/20 01:09
加载中...