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\n",maxn);
    return 0;
}
posted @ 2020-04-28 09:40  Valk3  阅读(104)  评论(0编辑  收藏  举报