zoukankan      html  css  js  c++  java
  • CF#633 D. Edge Weight Assignment

    D. Edge Weight Assignment

    题意

    给出一个n个节点的树,现在要为边赋权值,使得任意两个叶子节点之间的路径权值异或和为0,问最多,最少有多少个不同的权值。

    题解

    最大值:

    两个叶子节点x,y,如果他们的父亲都是z,那么[x,z],[y,z]的权值必须相同。

    其他边可以保证任意两个边的权值都不相同。

    最小值:

    如果任意两个叶子节点的路径长度为偶数,给所有边赋一个正值就可以。

    如果存在奇数:最少需要三个值。

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    
    vector<int>vec[N];
    int in[N],vis[N];
    int maxn;
    void dfs(int u,int pre,int col)
    {
        vis[u]=col;
        int num=0;
        for(int v:vec[u])
        {
            if(v==pre)
                continue;
            dfs(v,u,col^1);
            if(in[v]==1) num++;
        }
        if(num) maxn-=(num-1);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        maxn=n-1;
        for(int i=1; i<n; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            vec[u].pb(v);
            vec[v].pb(u);
            in[u]++,in[v]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(in[i]!=1)
            {
                dfs(i,0,0);
                break;
            }
        }
        int flag=0,num=0;
        for(int i=1;i<=n;i++)
        {
            if(in[i]==1)
            {
                num++;
                flag+=vis[i];
            }
        }
        if(flag!=0&&flag!=num)
        {
            if(n==2) printf("1 ");
            else printf("3 ");
        }
        else printf("1 ");
        printf("%d
    ",maxn);
        return 0;
    }
    
  • 相关阅读:
    单调栈
    单调队列
    线段树
    树状数组
    KMP模式匹配
    二分图最大匹配
    celery发送短信接口
    celery配置与基本使用
    celery介绍
    短信验证接口
  • 原文地址:https://www.cnblogs.com/valk3/p/12792038.html
Copyright © 2011-2022 走看看