80,WA四个点求助,跟题解一个做法
查看原帖
80,WA四个点求助,跟题解一个做法
30092
Meronri_Deng楼主2021/11/8 22:45

二分check部分在dfs(int x,int lst)
输出跟正解比偏小
如果可以希望给组较小的hack数据

int ans,N,M;//ans计数
int L=1,R,mid;
int zhi[MAXN];
multiset<int>	s[MAXN];
multiset<int>::iterator it;
void dfs(int x,int lst)
{
	for	(int i=head[x],y,z;i;i=e[i].next_)
		{
			y=e[i].to_,z=e[i].value_;
			if	(y==lst)	continue;
			dfs(y,x);
			if	(zhi[y]+z>=mid)	ans++;
						else	s[x].insert(zhi[y]+z);
		}
	zhi[x]=0;//先清零
	while	(!s[x].empty())
		{
			it=s[x].begin();
			int xx=*it;
			s[x].erase(it);//先删去最小数
			if	(s[x].empty())	{zhi[x]=xx;return;}//没数了直接退出
			it=s[x].lower_bound(mid-xx);
			if	(it!=s[x].end())	continue;//当前最小数匹配失败,忽略
			s[x].erase(it);
			ans++;//匹配成功的操作
		}
}
bool check()
{
	ans=0;
	dfs(1,-1);
	//printf("%d:%d\n",mid,ans);
	return ans>=M;
}
int Root;
void dfs0(int x,int lst,int now)
{
	if	(now>R)	R=now,Root=x;
	for	(int i=head[x],y,z;i;i=e[i].next_)
		{
			y=e[i].to_,z=e[i].value_;
			if	(y==lst)	continue;
			dfs0(y,x,now+z);
		}
}
void dfs1(int x,int lst,int now)
{
	R=now>R?now:R;
	for	(int i=head[x],y,z;i;i=e[i].next_)
		{
			y=e[i].to_,z=e[i].value_;
			if	(y==lst)	continue;
			dfs0(y,x,now+z);
		}
}
int main()
{
	freopen("P5021_17.in","r",stdin);
	//freopen("P5021_12.out","w",stdout);
	read(N),read(M);
	for	(int i=1;i<N;i++)
		{
			int x,y,z;read(x),read(y),read(z);
			Add(x,y,z),Add(y,x,z);
		}
	dfs0(1,-1,0);
	dfs1(Root,-1,0);
	while	(L<R)
		{
			mid=(L+R+1)>>1;
			if	(check())
				L=mid;
			else
				R=mid-1;
		}
	printf("%d\n",L);
 	return 0;
}

2021/11/8 22:45
加载中...