码迷,mamicode.com
首页 > 其他好文 > 详细

COJ 0346 WZJ的旅行(二)

时间:2015-08-02 23:09:37      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

 

WZJ的旅行(二)
难度级别:D; 运行时间限制:3000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

时隔多日,WZJ又来到了幻想国旅行。幻想国由N个城市组成,由于道路翻修,只有N-1条双向道路可以通行,第i条双向道路从ui连接到vi,距离为wi。但这N-1条道路竟然连接了整个国家,每两个城市之间都有一条道路!

WZJ知道这里景点很多,所以他想从城市s出发到城市t,旅游所有沿途的城市。WZJ想起到锻炼作用,但又不想太累,所以城市s到城市t的距离必须在L到R之间。另外WZJ规定s必须小于t,你能帮助他统计有多少对城市(s,t)符合要求吗?

输入
第一行为三个正整数N,L,R。
接下来N-1行每行为三个正整数ui,vi,wi。 
输出
输出多少对城市(s,t)符合要求。
输入示例
5 3 6
1 2 3
2 3 3
3 4 2
4 5 1
输出示例
6
其他说明
城市对(1,2)、(2,3)、(1,3)、(2,4)、(2,5)、(3,5)均符合要求,共计6对
1<=N<=100000
1<=L<=R<=10^9
1<=ui,vi<=N
1<=wi<=1000

题解:会写点分治了。。。

首先补集转换,不在同一个子树的 = 总的 - 在同一个子树的,那么就是求路径两段在同一个子树的,dfs一遍排序再金鸡独立大法求前缀,转成区间,然后就没了。

意会一下。。。(逃。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(‘ ‘)
 8 #define ENT putchar(‘\n‘)
 9 using namespace std;
10 const int maxn=100000+10,inf=-1u>>1;
11 struct ted{int x,y,w;ted*nxt;}adj[maxn<<1],*fch[maxn],*ms=adj;
12 void add(int w,int y,int x){
13     *ms=(ted){x,y,w,fch[x]};fch[x]=ms++;
14     *ms=(ted){y,x,w,fch[y]};fch[y]=ms++;
15     return;
16 }
17 bool vis[maxn];
18 int L,R,CG=1,siz[maxn],f[maxn],n,size;
19 void findcg(int x,int fa){
20     int mxs=-inf;siz[x]=1;
21     for(ted*e=fch[x];e;e=e->nxt){
22         int v=e->y;if(v!=fa&&!vis[v]){
23             findcg(v,x);siz[x]+=siz[v];
24             mxs=max(mxs,siz[v]);
25         }
26     }f[x]=max(mxs,size-siz[x]);
27     if(f[x]<f[CG])CG=x;return;
28 }
29 long long ans;
30 int A[maxn],dep[maxn],cnt;
31 void dfs(int x,int fa,int dist){
32     A[cnt++]=dist;
33     for(ted*e=fch[x];e;e=e->nxt){
34         int v=e->y;if(v!=fa&&!vis[v])dfs(v,x,dist+e->w);
35     }return;
36 }
37 long long cal(int x,int base){
38     cnt=0;dfs(x,0,base);long long res=0;
39     sort(A,A+cnt);
40     int l=0,r=cnt-1;while(l<r)if(A[l]+A[r]>R)r--;else res+=r-l++;
41     l=0;r=cnt-1;while(l<r)if(A[l]+A[r]>=L)r--;else res-=r-l++;
42     return res;
43 }
44 void solve(int x){
45     vis[x]=true;ans+=cal(x,0);
46     for(ted*e=fch[x];e;e=e->nxt){
47         int v=e->y;if(!vis[v]){
48             ans-=cal(v,e->w);
49             f[CG=0]=inf;size=siz[v];findcg(v,0);
50             solve(CG);
51         }
52     }return;
53 }
54 inline int read(){
55     int x=0,sig=1;char ch=getchar();
56     while(!isdigit(ch)){if(ch==-) sig=-1;ch=getchar();}
57     while(isdigit(ch)) x=10*x+ch-0,ch=getchar();
58     return x*=sig;
59 }
60 inline void write(long long x){
61     if(x==0){putchar(0);return;}if(x<0) putchar(-),x=-x;
62     int len=0;long long buf[15];while(x) buf[len++]=x%10,x/=10;
63     for(int i=len-1;i>=0;i--) putchar(buf[i]+0);return;
64 }
65 void init(){
66     n=read();L=read();R=read();
67     for(int i=1;i<n;i++)add(read(),read(),read());
68     f[CG=0]=inf;size=n;findcg(1,0);
69     solve(CG);write(ans);
70     return;
71 }
72 void work(){
73     return;
74 }
75 void print(){
76     return;
77 }
78 int main(){
79     init();work();print();return 0;
80 }

 

COJ 0346 WZJ的旅行(二)

标签:

原文地址:http://www.cnblogs.com/chxer/p/4696951.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!