C. Ehab and Path-etic MEXs
题目链接-C. Ehab and Path-etic MEXs
Note
The tree from the second sample:
题目大意
给一颗树,有 n 个顶点,给这个树的边分别编号为 0 (n−2),问怎样编使得对于树上任意两点 u,v 的最大 mex(u,v) 值最小。mex(u,v) 表示由 u 到 v 点的简单路径的长度构成的集合中,没有出现的最小非负整数
解题思路
贪心构造
- 如果存在某一个节点度数大于等于3(即不为链),那么三个出边分别连0 1 2就可以了,剩下的随便连,这样所有路径都不会同时经过0 1 2这三条边,所以mex最大值就是2
- 如果没有点度数大于等于3,那么这个树就是一条链,怎么赋值都无所谓了
- 具体操作见代码
附上代码
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e5+5;
typedef long long ll;
typedef pair<int,int> PII;
bool vis[N];
vector<int> vt[N];
int u[N],v[N],ans[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1;i<n;i++){
cin>>u[i]>>v[i];
vt[u[i]].push_back(v[i]);
vt[v[i]].push_back(u[i]);
}
int cnt=0;
for(int i=1;i<n;i++){
if(vt[u[i]].size()==1||vt[v[i]].size()==1){
vis[i]=1;
ans[i]=cnt++;
}
}
for(int i=1;i<n;i++){
if(!vis[i])
ans[i]=cnt++;
}
for(int i=1;i<n;i++)
cout<<ans[i]<<endl;
return 0;
}