首页 > 代码库 > 20140709

20140709

话说今天这个1个同学2002的题目真的有可总结性吗。

今天的结论是我的暴力又进化了,现在可以长达5KB,一节更比六节强。明天再来听评讲。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct edge{	long long to,d;	edge* next;};edge* head[5002],v[10004];long long ne=0,n,x,y,w,s,n1,n2;long long ca[5002][15],si1[5002],si2[5002],divv[5002];long long de[5002],di[5002];bool in[5002];void ad(long long a,long long b,long long c){	v[ne].to=b;	v[ne].d=c;	v[ne].next=head[a];	head[a]=&v[ne];	ne++;}void ss1(long long p){	in[p]=true;	divv[p]=1;	n1++;	si1[p]=1;	for (edge* z=head[p];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false)		{			ss1(z->to);			si1[p]+=si1[z->to];		}	}	return;}void ss2(long long q){	in[q]=true;	divv[q]=2;	n2++;	si2[q]=1;	for (edge* z=head[q];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false)		{			ss2(z->to);			si2[q]+=si2[z->to];		}	}	return;}void dfs1(long long p){	in[p]=true;	for (edge* z=head[p];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false)		{			de[z->to]=de[p]+1;			di[z->to]=di[p]+z->d;			dfs1(z->to);			ca[z->to][0]=p;		}	}	return;}void dfs2(long long q){	in[q]=true;	for (edge* z=head[q];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false)		{			de[z->to]=de[q]+1;			di[z->to]=di[q]+z->d;			dfs2(z->to);			ca[z->to][0]=q;		}	}	return;}long long lca(long long g,long long h){	long long k;	if (de[g]>de[h])	{		k=g;		g=h;		h=k;	}	for (int i=14;i>=0;i--)	{		if (de[ca[h][i]]>=de[g])		{			h=ca[h][i];		}	}	if (g==h) return h;	for (int i=14;i>=0;i--)	{		if (ca[g][i]!=ca[h][i])		{			g=ca[g][i];			h=ca[h][i];		}	}	return ca[h][0];}long long gogogo(long long p,long long q,long long y){	long long ans=0;	n1=0;	n2=0;	memset(ca,0,sizeof(ca));	memset(si1,0,sizeof(si1));	memset(si2,0,sizeof(si2));	memset(divv,0,sizeof(divv));	memset(in,false,sizeof(in));	divv[p]=1;	divv[q]=2;	ss1(p);	ss2(q);	long long t1=0,o1=p,t2=0,o2=q;	memset(in,false,sizeof(in));	in[p]=true;	in[q]=true;	for (edge* z=head[p];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false && si1[z->to]>t1)		{			t1=si1[z->to];			o1=z->to;		}		if (z->to!=-1) in[z->to]=true;	}	while (2*t1>n1 && n1!=1)	{		p=o1;		t1=0;		for (edge* z=head[p];z!=NULL;z=z->next)		{			if (z->to!=-1 && in[z->to]==false && si1[z->to]>t1)			{				t1=si1[z->to];				o1=z->to;			}			if (z->to!=-1) in[z->to]=true;		}	}	for (edge* z=head[q];z!=NULL;z=z->next)	{		if (z->to!=-1 && in[z->to]==false && si2[z->to]>t2)		{			t2=si2[z->to];			o2=z->to;		}		if (z->to!=-1) in[z->to]=true;	}	while (2*t2>n2 && n2!=1)	{		q=o2;		t2=0;		for (edge* z=head[q];z!=NULL;z=z->next)		{			if (z->to!=-1 && in[z->to]==false && si2[z->to]>t1)			{				t2=si2[z->to];				o2=z->to;			}			if (z->to!=-1) in[z->to]=true;		}	}	for (long long i=0;i<15;i++)	{		ca[p][i]=0;		ca[q][i]=0;	}	memset(di,0,sizeof(di));	memset(de,0,sizeof(de));	memset(in,false,sizeof(in));	dfs1(p);	dfs2(q);	for (long long i=1;i<15;i++)	{		for (long long j=1;j<=n;j++)		{			ca[j][i]=ca[ca[j][i-1]][i-1];		}	}	long long u1=0,u2=0;	for (long long i=1;i<n;i++)	{		for (long long j=i+1;j<=n;j++)		{			if (divv[i]==1 && divv[j]==1)			{				u1+=di[i]+di[j]-2*di[lca(i,j)];			}		}	}	for (long long i=1;i<n;i++)	{		for (long long j=i+1;j<=n;j++)		{			if (divv[i]==2 && divv[j]==2)			{				u2+=di[i]+di[j]-2*di[lca(i,j)];			}		}	}	ans+=n1*n2*y+u1+u2;	u1=0;	u2=0;	for (long long i=1;i<=n;i++)	{		if (divv[i]==1)		{			u1+=di[i];		}		else		{			u2+=di[i];		}	}	ans+=n1*u2+n2*u1;	return ans;}int main(){	freopen("testA.in","r",stdin);	freopen("testA.out","w",stdout);	cin>>n;	for (long long i=0;i<=n;i++)	{		head[i]=NULL;	}	for (long long i=1;i<n;i++)	{		cin>>x>>y>>w;		ad(x,y,w);		ad(y,x,w);	}	s=1000000000000000;	for (long long i=1;i<n;i++)	{		long long l,r;		r=v[i*2-2].to;		l=v[i*2-1].to;		v[i*2-2].to=-1;		v[i*2-1].to=-1;		s=min(s,gogogo(l,r,v[i*2-2].d));		v[i*2-2].to=r;		v[i*2-1].to=l;	}	cout<<s;	return 0;}

  暴得一手好力