【HBOI2013】Eden的博弈樹

題目

這裏寫圖片描述
對於 30%的數據, n ≤ 100 ;

對於 40%的數據, n ≤ 1,000 ;

對於 50%的數據, n ≤ 10 ,000 ,且樹是隨機生成的;

對於 100%的數據, 1 ≤ n ≤ 200 ,000 ,且對於節點 i(i ≠ 1),其父節點的編號小於 i。
這裏寫圖片描述

題意

這題的題意比較坑,不容易理解。
其實就是給你一棵樹,然後黑白染色。
染完色後,設最少需要染x個黑色點可以使得必勝,那麼這k個點便是最小黑方勝集合。
同理可以求出最小白方勝集合。並且這些點有可能有很多種情況
求出所有同是最小黑方勝集合和最小白方勝集合的交集的數目,最小編號,異或值
一個根要求勝的條件是:
若要求黑勝,則
這個點當前是黑色,則只要求它的子樹的任意一個點爲必勝即可。
這個點當前是白色,則要求它的子樹的每一個點都必須是必勝
白色類似

分析

我們可以這樣想,用f[i,j]表示當前根爲i時要求顏色j勝的最少需要確定的葉子節點的個數
轉移明顯,若i顏色和j不同,則f[i,j]=f[k,j]k 爲i的兒子。
若顏色相同,則f[i,j]=min(f[k,j])
葉子的點則是f[k,0]=f[k,1]=1;
然而我們考慮如何去算子集。
其實也很簡單,我們也是按照dp這樣去做,去選擇,
若當前顏色與j顏色不同,則遞歸每個它的兒子。
若一樣,則選最小的去遞歸,若有相同,則都遞歸即可。
這樣便可以很好解決問題了。

當然,留給讀者思考,若是分別求根的黑,白勝的方案,怎麼辦?

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#define maxlongint 2147483647
using namespace std;
const int N=200100;
int nu,n,b[N],las[N],nex[N],x,color[N],f[N][2];
bool bz[N][2];
void insert(int x,int y){
    b[++nu]=y;nex[nu]=las[x];las[x]=nu;
}
void dfs(int x){
    if (!las[x]) f[x][0]=f[x][1]=1;
    for(int p=las[x];p;p=nex[p]){
        color[b[p]]=color[x]^1;
        dfs(b[p]);
    }
}
void dfe(int x,int y){
    if (y==color[x]&&f[x][y]==0) f[x][y]=maxlongint;
    for(int p=las[x];p;p=nex[p]){
        dfe(b[p],y);
        if (y==color[x]) f[x][y]=min(f[x][y],f[b[p]][y]);
        else f[x][y]=f[x][y]+f[b[p]][y];
    }
}
void dfan(int x,int y){
    int pe=maxlongint;
    for(int p=las[x];p;p=nex[p]){
        if (y==color[x]) {
            if (pe>f[b[p]][y])pe=f[b[p]][y];
        }else dfan(b[p],y);
    }
    if (y==color[x]&&las[x]) for(int p=las[x];p;p=nex[p]) 
    if (f[b[p]][y]==pe) dfan(b[p],y);
    if (!las[x]) bz[x][y]=1;
}
int main(){
    scanf("%d",&n);
    for(int i=2;i<=n;i++) {
        scanf("%d",&x);
        insert(x,i);
    }
    color[1]=1;
    dfs(1);
    dfe(1,1);
    dfe(1,0);
    dfan(1,1);
    dfan(1,0);
    int an=0,ans=0,mi=maxlongint;
    for(int i=1;i<=n;i++){
        if (bz[i][1]&&bz[i][0]) {
            an++;mi=min(mi,i);ans=ans^i;
        }
    }
    printf("%d %d %d",mi,an,ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章