C. Ehab and Path-etic MEXs

C. Ehab and Path-etic MEXs

题意

给出一个n个节点的树,让你给每条边(n-1条)填上一个唯一的数( 0~n-2 ), 使得任意mex(u,v)的最大值最小

mex(u,v):表示从u到v这条路径上边权未出现过的数的最小的一个。

For example:
mex(u,v) 这条路径上的边权为1、3、4 (本题以0为最小值),mex(u,v)=0,0未出现过且最小。

思路

1.如果他就一条链,n-1条边从头到尾的mex(u,v) 就是n-1
2.如果他有支链(某个点的度>=3),我们就把0、1放到这个点的主链部分,把2放到这个点连接的支链部分,这样可以保证整个数的任意mex(u,v)最大值为2,是optimal.

可以这样想,我们的目的就是让0、1、2不在同一链路上,我们找一条链路上的所有边,每个点连接两条边,我们可以把最小的两个边0、1加到这个点(某个点的度>=3)两侧,并且这条链路上我们不放2这个边权,我们这时已经让这条链路的mex=2,再把2连接到这个点(就是保证0、1、2不在同一链路上),所以经过这个点的所有路径的最大mex为2,不经过这个点的所有mex=0

说的可能不明白,画图很清晰。

代码:找一个度为不小于3的点,让他的任意3条边等于0、1、2,其他边随机添加。

代码实现

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int n,u[maxn],v[maxn],w[maxn];
int ind[maxn];
int main(void){
    scanf("%d",&n);
    for(int i = 1; i < n; i++)
        scanf("%d%d",u+i,v+i),ind[u[i]]++,ind[v[i]]++,w[i]=-1;
    int m = 0;
    for(int i = 1; i <= n; i++)
        if(ind[i] >= 3){
            for(int j = 1; j < n; j++)
                if(u[j]==i||v[j]==i){
                    w[j]=m++;
                    if(m==3) break;
                }
            break;
        }
    for(int i = 1; i < n; i++)
        if(w[i]==-1) w[i] = m++;
    for(int i = 1; i < n; i++)
        printf("%d\n",w[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AC-AC/p/12503357.html
今日推荐