「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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM