[Difference] poj3417 on the number of trees doubled [] [] common ancestor lca

Topic Portal

Title effect, n-1 edges form a tree, given the m operation, the operation is not a two points, two points in the path tree plus one,
the output side of the tree that have attributes

F is obtained by multiplying the first array tree, a function of preparing for lca
+1 path between two points, a differential tree can be used, cnt] [x + 1, cnt + 1] y [
CNT [lca (x, y )] - = 2; sides achieve differential operation;
seeking prefix and, cnt [] array after differential;
using dfs recording sub-nodes and each point;

bool vis[N];
void dfs(int x) //求子树的权值和;
{
    vis[x]=true;
    for(int i=h[x];i!=-1;i=ne[i])
    {
        int y=e[i];
        if(vis[y]) continue;
        dfs(y);//求x的分枝中一个的权值和,
        cnt[x]+=cnt[y];
    }
}

#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<string.h>
using namespace std;
const int N=1e6;
int h[N],ne[N],e[N],idx;
int cnt[N];
void add(int a,int b)
{
    e[idx]=b;
   // w[idx]=c;
    ne[idx]=h[a];
    h[a]=idx++;
}
int n,m;
//最近公共祖先bfs部分,f[][]数组;
int f[N][30],t,d[N];

void bfs()
{
    queue<int>q;
    d[1]=1;
    q.push(1);
    while(q.size())
    {
        int x=q.front();
        q.pop();

        for(int i=h[x];i!=-1;i=ne[i])
        {
            int y=e[i];
            if(d[y]) continue;

            d[y]=d[x]+1;
            f[y][0]=x;
            for(int i=1;i<=t;i++)
            {
                f[y][i]=f[f[y][i-1]][i-1];
            }
            q.push(y);
        }
    }
}

int lca(int x,int y)
{
    if(d[x]<d[y]) swap(x,y);
    //单独跳;
    for(int i=t;i>=0;i--)
    {
        if(d[f[x][i]]>=d[y]) x=f[x][i];
    }
    if(x==y) return x;
    //一起跳
    for(int i=t;i>=0;i--)
    {
        //未相会,跳
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    }
    return f[x][0];
}
bool vis[N];
void dfs(int x)
{
    vis[x]=true;
    for(int i=h[x];i!=-1;i=ne[i])
    {
        int y=e[i];
        if(vis[y]) continue;
        dfs(y);
        cnt[x]+=cnt[y];
    }
}

int main()
{
    memset(h,-1,sizeof h);
    ios::sync_with_stdio(false);
    cin>>n>>m;
    t=(int)(log(n)/log(2))+1;
    for(int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    bfs();
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        cnt[lca(x,y)]-=2;
        cnt[x]+=1;
        cnt[y]+=1;
    }
    dfs(1);
    int  ans=0;
    for(int i=2;i<=n;i++)
    {
        if(cnt[i]==0) ans+=m;
        if(cnt[i]==1) ans++;
    }
    cout<<ans<<endl;
    return 0;
}

Published 152 original articles · won praise 4 · Views 3872

Guess you like

Origin blog.csdn.net/qq_43716912/article/details/100767671