CF1263F

タイトル説明

このようにAを与えます

図は、黒側の大部分を削除しようとすると、その結果、少なくとも一つのノード1と各特定のポイント通信

2つのツリーは、垂直配列が存在することを保証するために、1〜Nのために、特定のポイントDFSへようにアクセスされています

問題の解決策

セットF [i] [j]が選択された最後の点より特別ツリーを表す私の最小数、jは共感であります

各結合LCA - > MAX(i、j)は1パスは、確実にする対象DFSため以来、その法的状況にはありません

コード

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
using namespace std;

int a[10001][2];
int ls[5001];
int fa[2][5001][11];
int d[2][5001];
int f[1001][1001];
int n,A,B,i,j,k,l,len,ans;

void New(int x,int y)
{
    ++len;
    a[len][0]=y;
    a[len][1]=ls[x];
    ls[x]=len;
}

void dfs(int type,int t)
{
    int i;
    
    fo(i,1,10)
    fa[type][t][i]=fa[type][fa[type][t][i-1]][i-1];
    
    if (t<=n) return;
    
    for (i=ls[t]; i; i=a[i][1])
    {
        fa[type][a[i][0]][0]=t;
        d[type][a[i][0]]=d[type][t]+1;
        
        dfs(type,a[i][0]);
    }
}

void swap(int &x,int &y)
{
    int z=x;
    x=y;
    y=z;
}

int lca(int type,int x,int y)
{
    int i;
    
    if (!x)
    {
        if (!type)
        return n+1;
        else
        return n+A+1;
    }
    
    if (d[type][x]<d[type][y]) swap(x,y);
    
    fd(i,10,0)
    if (d[type][fa[type][x][i]]>=d[type][y])
    x=fa[type][x][i];
    
    fd(i,10,0)
    if (fa[type][x][i]!=fa[type][y][i])
    x=fa[type][x][i],y=fa[type][y][i];
    
    if (x!=y)
    x=fa[type][x][0];
    
    return x;
}

int main()
{
//  freopen("f.in","r",stdin);
    
    scanf("%d",&n);
    scanf("%d",&A);
    fo(i,2,A)
    {
        scanf("%d",&j);
        New(j+n,i+n);
    }
    fo(i,1,n)
    {
        scanf("%d",&j);
        New(j+n,i);
    }
    scanf("%d",&B);
    fo(i,2,B)
    {
        scanf("%d",&j);
        New(j+n+A,i+n+A);
    }
    fo(i,1,n)
    {
        scanf("%d",&j);
        New(j+n+A,i);
    }
    
    d[0][n+1]=d[1][n+A+1]=1;
    dfs(0,n+1);
    dfs(1,n+A+1);
    
    memset(f,127,sizeof(f));
    f[0][0]=0;
    
    fo(i,0,n-1)
    {
        fo(j,0,n-1)
        {
            k=max(i,j)+1;
            
            l=lca(0,i,k);
            f[k][j]=min(f[k][j],f[i][j]+(d[0][k]-d[0][l]-1));
            
            l=lca(1,j,k);
            f[i][k]=min(f[i][k],f[i][j]+(d[1][k]-d[1][l]-1));
        }
    }
    
    ans=2133333333;
    fo(i,0,n-1)
    ans=min(ans,min(f[i][n],f[n][i]));
    
    printf("%d\n",(A-1)+(B-1)-ans);
}

おすすめ

転載: www.cnblogs.com/gmh77/p/11961304.html