zoukankan      html  css  js  c++  java
  • 虎(思维题+树结构)

    OvO

    • 贪心

    • 对于一个节点来说,显然是对着的可以一条线连下来。所以偶数个的就正好是\(\frac{son}{2}\).
      然后对于奇数个的,那就是让偶数个先配上,剩下的一个向上传,这个是不影响父节点的。
      最后就是连边的时候,对于已经染成黑色的就不必再建边了。因为动一个已经黑色的不会更优。
      对于最后颜色没有要求的,这条边就没什么用处,但是需要它来连接其他边以达到更优解,所以用一种并查集的思想把这条边缩起来,让它的儿子和它的父亲相连即可。

    if(!y&&z)f[i]=to[x]; 
    if(!z)to[i]=to[x];
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1e6+1;
    int n;
    int f[maxn],to[maxn];
    bool vis[maxn];
    int ANS=0;
    int head[maxn],len=0;
    struct E{int to,next,w;}e[maxn<<1];
    void A(int x,int y){e[++len].to=y;e[len].next=head[x];head[x]=len;}
    int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);}
    void Dfs(int u){    
        vis[u]=1;
        int cnt=0;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            cnt++; 
            //printf("%d %d %d\n",u,v,cnt);
            Dfs(v); 
        }//printf("OvO %d %d\n",u,cnt);
        if(cnt&1){
            if(f[u])ANS+=(cnt-1)/2;
            else ANS+=(cnt+1)/2; 
        }
        else {
            ANS+=cnt/2; 
        }
    }
    int main(){
        freopen("tiger.in","r",stdin);
        freopen("tiger.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)to[i]=i;
        for(int i=2;i<=n;i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            if(!y&&z)f[i]=to[x]; 
            if(!z)to[i]=to[x];
        }//for(int i=1;i<=n;i++)printf("%d fa=%d\n",i,f[i]);
        for(int i=1;i<=n;i++){
            if(f[i])A(f[i],i);
        }for(int i=1;i<=n;i++){
            if(!vis[i]){
                Dfs(i);
            }
        }printf("%d\n",ANS);
        return 0;
    }
    
  • 相关阅读:
    [置顶] 十年博客行
    计算机编程语言年史
    初步认知MySQL metadata lock(MDL)
    Oracle语句优化规则(二)
    正则表达式
    sql server中的 SET NOCOUNT ON 的含义
    SQO (标准查询运算符)方法 & Linq To Object
    C# 扩展
    特性
    C#之泛型
  • 原文地址:https://www.cnblogs.com/13ZY/p/13799418.html
Copyright © 2011-2022 走看看