小度挪车

  • 子树余树的信息可以通过全局信息减去子树信息来统计
  • 在最后一刻,其实你已经意识到,问题大概出在((g[fa][0]-f[n1][0])+n-sum-cnt[n1][0])这个式子上
  • 但你最终没能找出错误,因为你只关注到式子的逻辑有没有问题,而没有意识到变量对式子的诠释是否恰当——
  • 你需要的其实是O节点的个数,但n代表的是所有节点的总个数
点击查看代码
#include <bits/stdc++.h> 
using namespace std;
vector<int>a[500005];
long long s[500005],d[500005],cnt[500005][2],sum,n;
bool c[500005],pd;
long long ans,f[500005][2],g[500005][2];
int read1()
{
    char cc=getchar();
    while(!(cc>=48&&cc<=57))
    {
        cc=getchar();
    }
    int s=cc-48;
    while(1)
    {
        cc=getchar();
        if(cc>=48&&cc<=57)
        {
            s=s*10+cc-48;
        }
        else
        {
            break;
        }
    }
    return s;
}
void dfs1(int n1,int fa)
{
    s[n1]=1;
    f[n1][c[n1]]=d[n1];
    cnt[n1][c[n1]]=1;
    for(int i=0;i<a[n1].size();i++)
    {
        if(a[n1][i]!=fa)
        {
            d[a[n1][i]]=d[n1]+1;
            dfs1(a[n1][i],n1);
            s[n1]+=s[a[n1][i]];
            f[n1][0]+=f[a[n1][i]][0];
            f[n1][1]+=f[a[n1][i]][1];
            cnt[n1][0]+=cnt[a[n1][i]][0];
            cnt[n1][1]+=cnt[a[n1][i]][1];
        }
    }
    if(s[n1]==sum||n-s[n1]==sum)
    {
        pd=true;
    }
}
void dfs2(int n1,int fa)
{
    for(int i=0;i<a[n1].size();i++)
    {
        if(a[n1][i]!=fa)
        {
            g[n1][0]=g[n1][0]+f[a[n1][i]][0];
            g[n1][1]=g[n1][1]+f[a[n1][i]][1];
        }
        else if(fa!=0)
        {
            g[n1][0]+=((g[fa][0]-f[n1][0])+n-sum-cnt[n1][0]);
            g[n1][1]+=((g[fa][1]-f[n1][1])+sum-cnt[n1][1]);
        }
    }
    for(int i=0;i<a[n1].size();i++)
    {
        if(a[n1][i]!=fa)
        {
            dfs2(a[n1][i],n1);
        }
    }
    if(s[n1]==sum)
    {
        ans=min(ans,f[n1][0]+g[fa][1]-f[n1][1]);
    }
    if(n-s[n1]==sum)
    {
        ans=min(ans,f[n1][1]+g[fa][0]-f[n1][0]);
    }
}
int main()
{
    cin>>n;
    string s;
    cin>>s;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='P')
        {
            c[i+1]=true;
            sum++;
        }
    }
    for(int i=1;i<n;i++)
    {
        int u,v;
        u=read1();
        v=read1();
        a[u].push_back(v);
        a[v].push_back(u);
    }
    d[1]=1;
    dfs1(1,0);
    if(pd==false)
    {
        puts("-1");
        return 0;
    }
    for(int i=1;i<=n;i++)
    {
        f[i][0]-=(cnt[i][0]*(d[i]-1));
		f[i][1]-=(cnt[i][1]*(d[i]-1));
    }
    ans=LLONG_MAX;
    dfs2(1,0);
    cout<<ans<<endl;
    return 0;
}
/*
10
OPPPOPPOPO
1 2
2 3
3 4
3 5
1 6
1 7
7 8
7 9
7 10

5
PPPPO
1 2
1 3
1 4
1 5
*/
posted @ 2024-07-06 20:36  D06  阅读(8)  评论(0编辑  收藏  举报