比赛 不平凡的世界 评测结果 AWWWWWWWWW
题目名称 不平凡的许愿树 最终得分 10
用户昵称 debug 运行时间 2.144 s
代码语言 C++ 内存使用 48.25 MiB
提交时间 2015-11-05 11:46:02
显示代码纯文本
#include<cstdio>
using namespace std;
int n;
int rudu[5555]={};
int weizhi[5555]={};
int weizhi2[5555]={};
int gen[5555]={};
int tou,wei;
int toppp[5555]={};
short temp[5001][5001]={};
int q[5555]={};
bool vis[5555]={};
bool vis2[5555]={};
long long ans=0;
short dis[5003]={};
int shuliang[5555]={};
struct ff
{
	int x,y;
}f[5555]={};
int g[11111]={};
void getdis(int a)
{
	for(int i=1;i<n;i++)
		toppp[i]=0;
	tou=0,wei=-1;
	q[++wei]=a;
	for(int i=1;i<=n;i++)
		vis[i]=0;
	vis[a]=1;
	int top=0;
	for(int i=1;i<=shuliang[a];i++)
		for(int j=1;j<n;j++)
			temp[i][j]=0;
	for(int i=weizhi[a];i<weizhi[a+1];i++)
	{
		for(int j=1;j<=n;j++)
			dis[j]=12345;
		dis[a]=0;
		top++;
		tou=0,wei=-1;
		q[++wei]=g[i];
		vis[g[i]]=1;
		dis[g[i]]=1;
		while(tou<=wei)
		{
			int te=q[tou];
			for(int j=weizhi[te];j<weizhi[te+1];j++)
			{
				if(dis[te]+1<dis[g[j]])
					dis[g[j]]=dis[te]+1;
				if(!vis[g[j]])
					q[++wei]=g[j],vis[g[j]]=1;
			}
			tou++;
		}
		for(int j=1;j<=n;j++)
			if(dis[j]<6666)
			temp[top][dis[j]]++;//temp[i][j] 第a个点对应第i个子树,距离为j的数量
	}
}
void gettop(int a)
{//进行松弛,压缩,将数量为零的距离跳过
	for(int i=1;i<n;i++)
	{
		for(int j=1;j<=shuliang[a];j++)
			if(temp[j][i]>0)
				temp[++toppp[i]][i]=temp[j][i];
	}
}
void getsum(int a)
{
	for(int i=1;i<n;i++)//枚举距离最多n-1
	{
		long long sss=0;
		long long ttt=0;
		for(int j=1;j<=toppp[i];j++)
			sss+=temp[j][i];
		ttt=sss*(sss-1)*(sss-2);
		for(int j=1;j<=toppp[i];j++)
			if(temp[j][i]>=3)
				ttt=ttt-temp[j][i]*(temp[j][i]-1)*(temp[j][i]-2);
		ttt/=6;
		ans=(ans+ttt)%233;
	}
}
int main()
{
	freopen("hopetree.in","r",stdin);
	freopen("hopetree.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<n;i++)
		scanf("%d%d",&f[i].x,&f[i].y),rudu[f[i].x]++,rudu[f[i].y]++;
	tou=0,wei=-1;
	for(int i=2;i<=n+1;i++)
		weizhi[i]=weizhi2[i]=weizhi[i-1]+rudu[i-1];
	for(int i=1;i<n;i++)
		g[weizhi2[f[i].x]]=f[i].y,g[weizhi2[f[i].y]]=f[i].x,weizhi2[f[i].x]++,weizhi2[f[i].y]++;
	for(int i=1;i<=n;i++)
		shuliang[i]=rudu[i];
	//先确定根节点位置
	//5000bfs求出每一点到所有点的距离即可
	//可以看出,当三点距离相等时,这三点必然离某一点的距离相等,所以计算所有两点间距离即可
	//由于是树,bfs遍历就行了
	for(int i=1;i<=n;i++)
		if(shuliang[i]>=2)
		getdis(i),gettop(i),getsum(shuliang[i]);
	int ans2=(ans+233)%338;
	printf("%d ",ans+1);
	printf("%d\n",ans2+1);
	return 0;
}