「CF1325C Ehab and Path-etic MEXs」

CF神奇构造题

题目大意

给出一颗 \(N\) 个节点树,每条边有边权,边权为 \(0\)\(N-2\) 的整数,且不重复,使得任意两点的简单路径的MEX的最大值最小.(MEX指第一个没有出现过的非负整数)

分析

对于MEX最重要自然是 \(0\),而且因为是树,所以必然可以做到将 \(0\)\(1\) 放入同一条树链中,那么就要考虑 \(2\) 的位置了,不可以让他出现在这条树链中,理解一下就是必须有一个点的度至少为 \(3\),即这个图不是一条链,那么就有一种非常容易的方法,将 \(0,1,2\) 放在三个度为 \(1\) 的点的边上,这样就不可能出现 \(0,1,2\) 同时出现在一条链上,其他也就可以乱放了,如果是一条链无论怎么放MEX都可以达到 \(N-1\),所以可以直接乱放.

代码

#include<bits/stdc++.h>
#define REP(i,first,last) for(int i=first;i<=last;++i)
#define DOW(i,first,last) for(int i=first;i>=last;--i)
using namespace std;
const int MAXN=114514;
int N,M;
int T;
int out[MAXN];//记录度
int p[MAXN];//比较懒,不想存图,所以就只记录一下每个点最后一条出边,反正最后有影响的之后度为1的点,所以没关系
int answer[MAXN];//记录答案
void work()
{
	scanf("%d",&N);
	int f,t;
	REP(i,1,N-1)
	{
		scanf("%d%d",&f,&t);
		out[f]++;
		out[t]++;
		p[f]=p[t]=i;
	}
	if(N==2)//注意特判2
	{
		printf("%d",0);
		return;
	}
	int cnt=0;
	REP(i,1,N)
	{
		if(out[i]==1)//在前三个度为1的点的出边赋值上0,1,2,为了方便处理这里就用了1,2,3
		{
			answer[p[i]]=++cnt;
			if(cnt==3)
			{
				break;
			}
		}
	}
	REP(i,1,N-1)//输出
	{
		if(answer[i])//如果有答案就输出答案
		{
			printf("%d\n",answer[i]-1);
		}
		else//没有反正可以乱输出
		{
			++cnt;
			printf("%d\n",cnt-1);
		}
	}
}
int main()
{
	work();
	return 0;
}
posted @ 2020-03-15 09:16  SxyLimit  阅读(625)  评论(2编辑  收藏  举报