1. 程式人生 > >【刷題】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程統計

【刷題】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程統計

ref utc NPU finish class AR long long its efi

Description

在得知了自己農場的完整地圖後(地圖形式如前三題所述),約翰又有了新的問題.他提供

一個整數K(1≤K≤109),希望你輸出有多少對農場之間的距離是不超過K的.

Input

第1到I+M行:與前三題相同;

第M+2行:一個整數K.

Output

農場之間的距離不超過K的對數.

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
10

Sample Output

5

有五對道路之間的距離小於10
1-4,距離為3
4-7,距離為2
1-7,距離為5
3-5,距離為7
3-6,距離為9

Solution

點分治
與【刷題】BZOJ 1468 Tree一模一樣
題目裏雖然是單向的,但是問的是距離,跟方向沒關系,直接雙向邊建上

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=40000+10,inf=0x3f3f3f3f;
int n,k,e,to[MAXN<<1],nex[MAXN<<1],beg[MAXN],w[MAXN<<1
],deep[MAXN],cnt,Msonsize[MAXN],size[MAXN],d[MAXN],root,finish[MAXN],m; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'
&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char ch='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch); } template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void insert(int x,int y,int z) { to[++e]=y; nex[e]=beg[x]; beg[x]=e; w[e]=z; } inline void getroot(int x,int f,int ntotal) { Msonsize[x]=0;size[x]=1; for(register int i=beg[x];i;i=nex[i]) if(to[i]==f||finish[to[i]])continue; else { getroot(to[i],x,ntotal); size[x]+=size[to[i]]; chkmax(Msonsize[x],size[to[i]]); } chkmax(Msonsize[x],ntotal-size[x]); if(Msonsize[x]<Msonsize[root])root=x; } inline void getdeep(int x,int f) { deep[++cnt]=d[x]; for(register int i=beg[x];i;i=nex[i]) if(to[i]==f||finish[to[i]])continue; else d[to[i]]=d[x]+w[i],getdeep(to[i],x); } inline int calc(int x,int st) { d[x]=st;cnt=0; getdeep(x,0); std::sort(deep+1,deep+cnt+1); int l=1,r=cnt,ans=0; while(l<r) { if(deep[l]+deep[r]<=k)ans+=r-l,l++; else r--; } return ans; } inline int solve(int x) { int res=calc(x,0); finish[x]=1; for(register int i=beg[x];i;i=nex[i]) if(!finish[to[i]]) { res-=calc(to[i],w[i]); root=0; getroot(to[i],x,size[to[i]]); res+=solve(root); } return res; } int main() { read(n);read(m); for(register int i=1;i<=m;++i) { int u,v,w; char s; read(u);read(v);read(w);std::cin>>s; insert(u,v,w);insert(v,u,w); } read(k); Msonsize[0]=inf;root=0; getroot(1,0,n); write(solve(1),'\n'); return 0; }

【刷題】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程統計