标签:
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 }
标签:
原文地址:http://www.cnblogs.com/chxer/p/4696951.html