CSPの練習試合0925

ねえ、まだあまりにもnaiive
ABの質問は、私はZZ、約来ただけで1.5HB問題も1Hを取っノックし、
まだ非常に慎重に
最終検査は、敏感な問題0があることが判明しました

Cの質問は、私が見るようになりましたか?この問題はそれほど水は井戸も半分行うライン上のすべての二つのノードのために交尾していないで
、私は間違いがなければならないと思っています権利を!
そして、私が間違っている必要があります考えるのは大きなサンプルを見てください!

それから私は私が何をしたいウェーブテーブルは、ああ、私の神はこれがない練習の最後の数分を果たしました

実際には非常に安定したが、それでもあまりにnaiiveメンタリティ

サンプルは、経験を理解していなかったので、主にそれがでした。

サンプルは慎重にテーブルのああを再生するために読まれるべきです

3、スプリットケーブル(tree.pas / CPP)
[問題の説明]
ペンギン米国インターネットとの間がケーブルで接続されている、ツリー構造が形成されます。さて冬、暖房ユニット、その
燃料のドアがないので、彼らは燃料を行うには、ネットワークケーブルの一部を解体することにしました。しかし、今、インターネットや他のオンラインへのKのペンギンがある
ゲームは、そう、彼らはその後、(戦う同じ部屋に2羽のペンギンを)別の部屋を手配Kペンギンを配置する必要が
ケーブルの番号の後に削除されますが、それぞれのことを確認する必要がありますペンギンは、少なくともケーブルと少なくとも一つの他のペンギンオンラインを通じて滞在することができます
ゲーム。
だから彼らは保持されるように、ネットワークケーブルの必要性の最小数を知りたいですか?

:ソリューション
最大独立集合
DFS又はから開始貪欲リーフノードまたはDP
の縁の最大数はFを定義[I]は[1/0]私は独立のセットの最大点としてサブツリーのノードiを選択しました

\(F [i]が[0] = \和F [U] [1] \)

\(F [i]が[1] = MAX(F [i]が[0] -f [U] [1] +1); \)


コード:

 

#include<stdio.h>
#include<bits/stdc++.h> 
using namespace std; 
#define maxnn 200100 
#define ll long long 
int las[maxnn],nex[maxnn],en[maxnn],tot; 
int n; 
int f[maxnn>>1][2];  
int T; 
int m; 
void add(int a,int b) { 
    en[++tot]=b; 
    nex[tot]=las[a]; 
    las[a]=tot; 
} 
void dfs(int v,int fa) 
{ 
    for(int i=las[v];i;i=nex[i]) 
    { 
        int u=en[i]; 
        if(u!=fa) 
        { 
            dfs(u,v); 
            f[v][0]+=f[u][1]; 
        } 
    } 
        for(int i=las[v];i;i=nex[i]) 
    { 
        int u=en[i]; 
        if(u!=fa) 
        { 
            f[v][1]=max(f[v][1],f[v][0]+f[u][0]-f[u][1]+1); 
        } 
    } 
     
} 
int main() { 
//  freopen("tree.in","r",stdin);
//  freopen("ooo","w",stdout);
    cin>>T; 
    int x,y,z; 
    while(T--) 
    { 
         for(int i=1;i<=n;i++) 
         f[i][0]=f[i][1]=0;
        scanf("%d%d",&n,&m);  
         for(int i=1;i<=tot;i++)
        {
            las[i]=0;
            nex[i]=0;
            en[i]=0;
        }
        tot=0;
        for(int i=1;i<n;i++)
       {
            scanf("%d",&x); 
            add(x,i+1); 
            add(i+1,x); 
        }
        dfs(1,1);
    
        int d=max(f[1][1],f[1][0]); 
        
        if(2*d>=m) 
        { 
            printf("%d\n",(m+1)/2); 
        } 
        else 
        { 
            printf("%d\n",d+m-2*d); 
        } 
    } 
} 

おすすめ

転載: www.cnblogs.com/OIEREDSION/p/11588403.html