bzoj 3365 [Usaco2004 Feb]Distance Statistics 路程统计(点分治,单调)
【题意】
求树上长度不超过k的点对数目。
【思路】
和 Tree 一样一样的。
就是最后统计的时候别忘把根加上。
【代码】
1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 11 using namespace std; 12 13 typedef long long ll; 14 const int N = 2e5+10; 15 16 ll read() { 17 char c=getchar(); 18 ll f=1,x=0; 19 while(!isdigit(c)) { 20 if(c=='-') f=-1; c=getchar(); 21 } 22 while(isdigit(c)) 23 x=x*10+c-'0',c=getchar(); 24 return x*f; 25 } 26 27 struct Edge { 28 int v,w,nxt; 29 }e[N<<1]; 30 int en=1,front[N]; 31 void adde(int u,int v,int w) 32 { 33 e[++en]=(Edge){v,w,front[u]}; front[u]=en; 34 } 35 36 int n,m,K,ans; 37 int rt,size,list[N],vis[N],dis[N],siz[N],f[N],l1,l2; 38 39 bool cmp(const int& x,const int& y) 40 { 41 return dis[x]<dis[y]; 42 } 43 void get_root(int u,int fa) 44 { 45 siz[u]=1; f[u]=0; 46 trav(u,i) if(!vis[e[i].v]&&e[i].v!=fa){ 47 int v=e[i].v; 48 get_root(v,u); 49 siz[u]+=siz[v]; 50 if(f[u]<siz[v]) f[u]=siz[v]; 51 } 52 f[u]=max(f[u],size-siz[u]); 53 if(f[u]<f[rt]) rt=u; 54 } 55 void dfs(int u,int fa) 56 { 57 list[++l1]=u; 58 trav(u,i) 59 if(!vis[e[i].v]&&e[i].v!=fa) { 60 int v=e[i].v; 61 dis[v]=dis[u]+e[i].w; 62 dfs(v,u); 63 } 64 } 65 int get_ans(int l,int r) 66 { 67 sort(list+l,list+r+1,cmp); 68 int j=r,ans=0; 69 for(int i=l;i<=r;i++) { 70 while(j>i&&dis[list[j]]+dis[list[i]]>K) j--; 71 ans+=j-i; if(i==j) break; 72 } 73 return ans; 74 } 75 void solve(int u) 76 { 77 vis[u]=1; l1=l2=0; 78 trav(u,i) if(!vis[e[i].v]) { 79 int v=e[i].v; 80 dis[v]=e[i].w; 81 dfs(v,-1); 82 ans-=get_ans(l2+1,l1); 83 l2=l1; 84 } 85 list[++l1]=u; dis[u]=0; 86 ans+=get_ans(1,l1); 87 trav(u,i) if(!vis[e[i].v]) { 88 rt=0; get_root(e[i].v,-1); 89 size=siz[e[i].v]; 90 solve(rt); 91 } 92 } 93 94 int main() 95 { 96 n=read(),m=read(); 97 int u,v,w; char s[5]; 98 FOR(i,1,m) { 99 u=read(),v=read(),w=read(); 100 adde(u,v,w),adde(v,u,w); 101 scanf("%s",s); 102 } 103 K=read(); 104 size=f[0]=n; 105 get_root(1,-1); 106 solve(rt); 107 printf("%d\n",ans); 108 return 0; 109 }
posted on 2016-03-27 16:56 hahalidaxin 阅读(404) 评论(0) 编辑 收藏 举报