暑 假 队 测 Round #1

暑假第一次队测就被吊起来打了。。

\(50+37+100=187pts\)

T1国王游戏
T2没找到,题目大意
T3Computer Network

T1:贪心

是个很经典的邻项微扰,可惜不会打高精(wtcl)...

T2:DFS

n和m的数据范围很明显是在暗示dfs+剪枝了,
我这个睿智还是码了个01背包。。。
37滚粗。

T3:Tree Dp

唯一一个AC的题

口胡做法:
二次扫描+换根,结点可以用离父亲结点远与远的值来更新
这取决与结点是否位于父亲结点的最长链上。

感觉最近dp水平进步还挺快
然后因为一些sb错误改了很久,幸好最后de出来了。

T3Code:

#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;
int n,pre[N],now[N],to[N],tot;
int d[N][3],f[N],ins[N];
int lst[N];
void add(int x,int y){
	pre[++tot]=now[x];
	to[tot]=y;now[x]=tot;
}
void dfs(int u,int fa){
	for(int i=now[u];i;i=pre[i]){
		int v=to[i];
		if(v==fa)continue;
		dfs(v,u);
		if(d[u][1]==d[u][2]&&d[u][1]==0)
			d[u][1]=d[u][2]=1;
		if(d[u][1]<=d[v][1]+1){
			swap(d[u][1],d[u][2]);
			d[u][1]=d[v][1]+1;
			ins[lst[u]]=0;
			ins[v]=1;
			lst[u]=v;
		}
		else d[u][2]=max(d[u][2],d[v][1]+1);
	}
}
void DFS(int u,int fa){
	for(int i=now[u];i;i=pre[i]){
		int v=to[i];
		if(v==fa)continue;
		f[v]=max(f[v],f[u]+1);
		if(ins[v]==1)
			f[v]=max(f[v],d[u][2]+1);
		else f[v]=max(f[v],d[u][1]+1);
		DFS(v,u);
	}
}
int main(){
	//freopen("tree.in","r",stdin);
	//freopen("tree.out","w",stdout);
	scanf("%d",&n);
	for(int i=1,u,v;i<n;i++){
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	dfs(1,0);
	DFS(1,0);
	for(int i=1;i<=n;i++)
		printf("%d\n",max(f[i],d[i][1]));
	return 0;
}
原文地址:https://www.cnblogs.com/Xxhdjr/p/13387223.html