西安邮电大学第五届ACM-ICPC校赛 C题 异或生成树(树形dp)

显然我们看到数据范围这么小,就很自然的想到dp。所以可以把状态设成以i为根节点可以异或出的答案是j

这样我们先对子树进行操作,之后枚举二维来暴力异或更新。

在更新的时候,千万不能直接拿原数组更新,而要存一个备份数组,因为如果拿原数组更新,很可能出与某个子树更新的答案又继续跟当前子树更新,从而多出答案。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<functional>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<map>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int f[110][1100];
int h[N],ne[N],e[N],w[N],idx;
int a[N];
int tmp[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int fa){
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        dfs(j,u);
        for(int k=0;k<=128;k++)
            tmp[k]=f[u][k];
        for(int k=0;k<=128;k++)  
            for(int l=0;l<=128;l++)
            if(tmp[k]&&f[j][l]){
                f[u][k^l]=1;
            }
    }
    f[u][0]=1;
}
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    memset(h,-1,sizeof h);
    for(i=1;i<=n;i++){
        cin>>a[i];
        f[i][a[i]]=1;
    }
    for(i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    dfs(1,-1);
    int res=0;
    for(i=1;i<=n;i++){
        for(int j=1;j<=128;j++){
            if(f[i][j])
                res=max(res,j);
        }
    }
    cout<<res<<endl;
}
View Code

猜你喜欢

转载自www.cnblogs.com/ctyakwf/p/12944193.html
今日推荐