3.9模拟赛 T1 树上博弈

image

image

分类好题,可惜考的时候没做出来
https://oj.bashu.com.cn/code/problempage.php

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i <= b;i++)
#define ll long long
using namespace std;
const int maxn = 1e6 + 5;
const int inf = 1e9 + 7;
struct node{
	int nex;
	int to;
	double w;
}a[maxn];
int hd[maxn],cnt;
double dis[maxn];
int n,rt, ans[maxn], pre[maxn], D;
int G[maxn],cntg, H[maxn];
void ru(int x,int y, double z)
{
	a[++cnt].to = y;
	a[cnt].w = z;
	a[cnt].nex = hd[x];
	hd[x] = cnt;
}

void dfs1(int x, int fa)
{
	pre[x] = fa;
	if(x == rt) 
		dis[x] = 0;
		
	for(int i = hd[x];i;i = a[i].nex)
	{
		int v = a[i].to;
		if(v == fa) continue;
		dis[v] = dis[x] + a[i].w;
		dfs1(v, x);
	}
	return ;
}

void dfs2(int x,int fa,int jl)
{
	if(jl == 0)
	{
		if(D % 2 == 0)
		{
			rt = x;
		}
		else //虚点 
		{
			for(int i = hd[x];i;i = a[i].nex)
			{
				int v = a[i].to;
				if(v == fa)
				{
					a[i].to = n + 1;
					a[i].w = 0.5;
					break;
				}
			}
			for(int i = hd[fa];i;i = a[i].nex)
			{
				int v = a[i].to;
				if(v == x)
				{
					a[i].to = n + 1;
					a[i].w = 0.5;
					break;
				}
			}
			ru(n + 1, fa, 0.5);
			ru(n + 1, x, 0.5); 
			rt = n + 1;
		}
		return ;
	}
	
	dfs2(pre[x],x,jl - 1);
}

void dfs3(int x, int fa,int zuxian, double jl)
{
	if(jl == 0)
	{
		if(G[zuxian] == 0) 
			cntg++;
		G[zuxian] ++;
		return ;
	}
	
	if(jl == 1.0)
		H[zuxian] ++;	
			
	for(int i = hd[x];i;i = a[i].nex)
	{
		int v = a[i].to;
		if(v == fa) continue;
		dfs3(v, x, zuxian, jl - a[i].w);
	}
	return ;
}

int pd()
{
	
	if( (cntg >= 4) || (cntg == 3 && n % 2 == 1) )//1 2 D
		return D;
	if(cntg == 3)
	{
		int ji = 0;
		for1(i,1,n)
			if(G[i] >= 2)
				ji++;
				
		if(ji >= 1 )//3 D
			return D ;
		
		if(ji == 0 && n % 2 == 0)//1 D - 1
			return D - 1;
	}
	if(cntg == 2)
	{
		int ji = 0;
		for1(i,1,n)
			if(G[i] >= 2)
				ji++;
				
		if( (ji == 2) )//4 D
			return D ;
		
		if( ji >= 1 && n % 2 == 1)//5 D
			return D ;
		
		if( ji >= 1 && n % 2 == 0)//2 D - 1
			return D - 1;
		
		if(ji == 0)
		{
			if(n % 2 == 1)//D - 1 3
				return D - 1;
			
			//last D - 1  or D - 2
			int ja = 0,jb = 0;
			for1(i,1,n)
				if(G[i])
				{
					if(ja == 0)
						ja = i;
					else 
						jb = i;	
				}
			int h1 = 0, h2 = 0, h3 = 0;
			for1(i,1,n)
			{
				if(H[i] > 0 && i != ja && i != jb)
					h3 += H[i];
				else if(i == ja)
					h1 += H[i];
				else if(i == jb)
					h2 += H[i];
			}
			
			if(h3 >= 2)
			return D - 1;
			
			if( h1 >= 2 && h2 >= 2 )
				return D - 1;
			 if( (h1 > 1 || h2 > 1) && h3 == 1)
				return D - 1;
		}	
	}
	return D - 2;
}
main()
{
	cin >> n;
	int x, y;
	for1(i,1,n - 1)
	{
		cin >> x >> y;
		ru(x, y, 1);
		ru(y, x, 1);
	}
	
	dis[0] = -1;
	dfs1(1,0);
	
	int ji = -1;
	for1(i,1,n)
		if(ji < dis[i])
			rt = i,ji = dis[i];
			
	dfs1(rt,0);
	
	D = -1;
	for1(i,1,n)
		D = max(D,(int)dis[i]);
		
	ji = -1;
	for1(i,1,n)
		if(ji < dis[i])
			rt = i,ji = dis[i];
			
	if(D % 2 == 0)
		dfs2(rt,0,D/2);
	else
		dfs2(rt,0,D/2 + 1);

	dfs1(rt,0);
	
	for(int i = hd[rt];i;i = a[i].nex)
	{
		int v = a[i].to;
		if(v == rt) continue;
		dfs3(v, rt, v, (1.0*D) / 2 - a[i].w);
	}
	
	cout<<pd();
	return 0;
}
posted @ 2023-03-09 16:53  yyx525jia  阅读(17)  评论(0)    收藏  举报