话说今天这个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; }
暴得一手好力
原文地址:http://www.cnblogs.com/201312lyx/p/3834509.html