[poj1987]Distance Statistics
同[poj1741]Tree。。。
(不过说好的数据范围呢。。。)

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 8 char s[10]; 9 int n,m,k; 10 const int N=100000; 11 int h[N],to[N],r[N],w[N],ans,tot,num,root,deep[N],d[N],sz[N],f[N],v[N],sum; 12 void ins(int u,int v,int z){ 13 to[tot]=v; 14 w[tot]=z; 15 r[tot]=h[u]; 16 h[u]=tot++; 17 } 18 19 void getDeep(int x,int fa){ 20 deep[++num]=d[x]; 21 for(int i=h[x];i!=-1;i=r[i]){ 22 if(!v[to[i]]&&to[i]!=fa){ 23 d[to[i]]=d[x]+w[i]; 24 getDeep(to[i],x); 25 } 26 } 27 } 28 void getRoot(int x,int fa){ 29 sz[x]=1; 30 f[x]=0; 31 for(int i=h[x];i!=-1;i=r[i]){ 32 if(!v[to[i]]&&to[i]!=fa){ 33 getRoot(to[i],x); 34 sz[x]+=sz[to[i]]; 35 f[x]=max(f[x],sz[to[i]]); 36 } 37 } 38 f[x]=max(f[x],sum-sz[x]); 39 if(f[x]<f[root])root=x; 40 } 41 int calc(int x,int val,int t=0){ 42 d[x]=val; 43 num=0; 44 getDeep(x,0); 45 sort(deep+1,deep+1+num); 46 for(int l=1,r=num;l<r;){ 47 if(deep[l]+deep[r]<=k){t+=r-l;l++;} 48 else r--; 49 } 50 return t; 51 } 52 void work(int x){ 53 ans+=calc(x,0); 54 v[x]=1; 55 for(int i=h[x];i!=-1;i=r[i]){ 56 if(!v[to[i]]){ 57 ans-=calc(to[i],w[i]); 58 root=0; 59 sum=sz[to[i]]; 60 getRoot(to[i],0); 61 work(root); 62 } 63 } 64 } 65 66 int main(){ 67 memset(h,-1,sizeof(h)); 68 scanf("%d%d",&n,&m); 69 for(int i=1,u,v,z;i<=m;i++)scanf("%d%d%d%s",&u,&v,&z,s),ins(u,v,z),ins(v,u,z); 70 scanf("%d",&k); 71 f[0]=0x3f3f3f3f; 72 sum=n; 73 getRoot(1,0); 74 work(root); 75 printf("%d\n",ans); 76 }