Ehab and Path-etic MEXs(思维+构造)

https://www.luogu.com.cn/problem/CF1325C

题意翻译

给定一个 nn 个节点 n-1n−1 条边的树

要求给边重新标注边权

分别为 0,1,2...n-20,1,2...n−2 。

然后使得树上任意两点 u,vu,v 的 \mathrm{MEX}(u,v)MEX(u,v) 的最大值最小。

\mathrm{MEX}(u,v)MEX(u,v) 是 uu 到 vv 的简单路径没有出现的自然数中最小的数。

翻译人:do_while_false


 思路:树构造可以先尝试从小的链子开始,可以发现小的链子上只能是全部数字都存在。那么稍微变化一点,变成一棵树,那么会发现总能存在一条路包含0和1,那么尝试构造0,1,2不在同一条路上。

把 0,1,2 作为与这个结点相邻的任意 3 个结点与其连边的边权,其他边随意赋值即可,这样 保证最小值为2。

用邻接表存下每个点后面连的是第几号边,同时统计每个点的度数,遇到了>=3的度数的点的时候把这个点对应的三条边全部标记成0,1 ,2.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL deg[maxn],cnt;
LL vis[maxn];
vector<LL>g[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  for(LL i=1;i<n;i++)
  {
  	LL a,b;cin>>a>>b;g[a].push_back(i);g[b].push_back(i);
  	deg[a]++;deg[b]++;
  }
  bool flag=1;
  for(LL i=1;i<n;i++){
  	if(deg[i]>=3) flag=0;
  }
  if(flag==1){
  	LL ans=0;
	for(LL i=0;i<n-1;i++){
  		cout<<i<<endl;
	}
	return 0;
  }
  LL num=0;
  for(LL i=1;i<=n;i++)
  {
	if(deg[i]>=3)
	{
		for(LL j=0;j<3;j++) vis[g[i][j]]=++num;
		break;
	}
  }
  for(LL i=1;i<n;i++) if(!vis[i]) vis[i]=++num;
  for(LL i=1;i<n;i++) cout<<vis[i]-1<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108890804
今日推荐