[USACO20FEB]Delegation P 题解

题意: \(n\) 个节点的树,边权为1,你需要求出将这颗树拆分成若干条链时链的长度最小值的最大值。

赛道修建 类似,都是二分一个 \(mid\), 然后能在当前子树内成链则成链,否则向上延伸,只不过这道题需要满足剩下的链的数量不能超过1。还有,如果当前点的子节点即连接的链是偶数个,那就加入一个0,使得他能至少向上贡献一条链。
坑点: (!x&1)(!(x&1)) 的判定结果是不同的 ,因为这个调了半个小时,mdzz。

#include<bits/stdc++.h>

#define int long long

using namespace std;

int read()
{
	int ret=0, f=1; char x=getchar();

	while(!isdigit(x)) { if(x=='-') f=-1; x=getchar(); }

	while(isdigit(x)) { ret=ret*10+x-'0'; x=getchar(); }

	return ret*f;
}

const int maxn=1e5+3;

vector <int> vec[maxn];

int head[maxn],nxt[maxn<<1],to[maxn<<1], cnt;

void add_edge(int x,int y)
{
	cnt++; to[cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
}

int d[maxn],lst[maxn];

bool work(int p,int x,int limt)
{
	for(int i=0,j=(signed)vec[x].size()-1;i<j;i++,j--)
	{
		if(i==p) i++;

		if(j==p) j--;

		if(vec[x][i]+vec[x][j]<limt) { return 0; }
	}

	return 1;
}

int flg;

void dfs(int x,int fa,int limt)
{
	vec[x].clear();

	for(int i=head[x];i;i=nxt[i])
	{
		int v=to[i]; if(v==fa) continue;

		dfs(v,x,limt);

		vec[x].push_back(lst[v]+1);
	}

	int siz=vec[x].size();

	if(!fa) { if(siz&1) { vec[x].push_back(0); siz++; } }

	else { if(!(siz&1)) { vec[x].push_back(0); siz++; } }

	sort(vec[x].begin(), vec[x].end());

	if(!fa)
	{
		for(int i=0;i<siz/2;i++)
		{
			if(vec[x][i]+vec[x][siz-i-1]<limt) { flg=0; return; }
		}
	}

	else
	{
		if(!work(0,x,limt)) { flg=0; return; }

		else
		{
			int l=0,r=siz-1;

			while(l<r)
			{
				int mid=(l+r+1)>>1;

				if(work(mid,x,limt)) { l=mid; }

				else { r=mid-1; }
			}

			lst[x]=vec[x][l];
		}
	}
}

void check(int x)
{
	flg=1;

	dfs(1,0,x);
}

signed main()
{
	int n=read();

	for(int i=1;i<n;i++) { int x=read(), y=read(); d[x]+=1; d[y]+=1; add_edge(x,y); add_edge(y,x); }

	int l=1,r=n-1;

	while(l < r)
	{
		int mid=(l+r+1)>>1; check(mid);

		cerr << l << " " << r << " " << mid << " " << flg << endl ;

		if(flg) { l=mid; } else { r=mid-1; }
	}

	check(l); cerr << flg << endl; int ans= flg ? l : 0 ;

	cout << ans << endl ;

	return 0;
}
posted @ 2021-05-17 19:34  Van-Helsing  阅读(80)  评论(0)    收藏  举报