比赛 防止浮躁的小练习V0.1 评测结果 AAAAAAAAAAAAA
题目名称 政党 最终得分 100
用户昵称 Hzoi_Queuer 运行时间 2.488 s
代码语言 C++ 内存使用 34.64 MiB
提交时间 2016-10-07 17:53:33
显示代码纯文本
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=300005;
struct Edge{
	int to,next;
}e[maxn<<1];
int n,m,len=0,Deep;
int head[maxn],d[maxn],fa[maxn][20],dis[maxn];
vector<int> pol[maxn];

void Insert(int x,int y){
	len++;e[len].to=y;e[len].next=head[x];head[x]=len;
}

void Build(int x,int deep){
	d[x]=deep;
	for(int i=head[x];i!=-1;i=e[i].next){
		int j=e[i].to;
		if(!fa[j][0]){
			fa[j][0]=x;
			Build(j,deep+1);
		}
	}
}

int LCA(int x,int y){
	if(d[x]<d[y])swap(x,y);
	for(int i=Deep-1;i>=0;i--){
		if(d[fa[x][i]]>=d[y])
			x=fa[x][i];
	}
	if(x==y)return x;
	for(int i=Deep-1;i>=0;i--){
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];y=fa[y][i];
		}
	}
	return fa[x][0];
}

int Work(int x){
	int s=pol[x][0],j,ans=0;
	for(int i=0;i<pol[x].size();i++){
		int rt=LCA(s,pol[x][i]);
		int dis=d[s]+d[pol[x][i]]-2*d[rt];
		if(ans<dis){ans=dis,j=pol[x][i];}
	}
	for(int i=0;i<pol[x].size();i++){
		int rt=LCA(j,pol[x][i]);
		int dis=d[j]+d[pol[x][i]]-2*d[rt];
		if(ans<dis)ans=dis;
	}
	return ans;
}

int main()
{
	freopen("cowpol.in","r",stdin);
	freopen("cowpol.out","w",stdout);
	memset(head,-1,sizeof head);
	scanf("%d%d",&n,&m);int x,y;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		pol[x].push_back(i);
		if(!y)continue;
		Insert(i,y);Insert(y,i);
	}
	Deep=(int)(log(1.0*n)/log(2.0))+1;
	for(int i=1;i<=n;i++){
		if(!fa[i][0]){
			fa[i][0]=i;
			Build(i,1);
		}
	}
	for(int j=1;j<Deep;j++){
		for(int i=1;i<=n;i++){
			fa[i][j]=fa[fa[i][j-1]][j-1];
		}
	}
	for(int i=1;i<=m;i++)printf("%d\n",Work(i));
	return 0;
}