路径(2015升级版) |
难度级别:D; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
试题描述
|
WZJ在生日当天决定在他的领地举行一场马拉松比赛,他的领地有N座城市,是通过道路相连组成了一个N-1条边的无向无环图。每条边由ai连到bi,距离为ci。WZJ决定选取两个城市分别为起点和终点,举行比赛。比赛时按这两个城市间的最短距离进行比赛。WZJ想选出一条尽量长的路径,但由于资金限制,路径长最多不能超过k。你能帮帮他吗?
|
输入
|
第一行为两个正整数N,k,表示N个城市,最长距离为K。
接下来N-1行为ai,bi,ci,表示有一条边从ai到bi,距离为ci。 |
输出
|
输出路径在小于k的情况下的最长长度。
|
输入示例
|
5 7
1 2 3 1 3 4 4 5 7 4 2 2 |
输出示例
|
7
|
其他说明
|
1<=N<=50000
1<=ai,bi<=N 1<=ci<=k<=10^9 起点为2,终点为3. 放心,不是O(nlog^2n)是过不了的! |
题解:点分治,看好那个find函数。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #include<ctime> 8 #define PAU putchar(' ') 9 #define ENT putchar(' ') 10 #define CH for(int d=0;d<2;d++)if(ch[d]) 11 using namespace std; 12 const int maxn=50000+10,maxm=100000+10,inf=-1u>>1; 13 struct node{ 14 node*ch[2];int r,siz,v; 15 void init(){r=rand();siz=1;ch[0]=ch[1]=NULL;return;} 16 void update(){siz=1;CH{siz+=ch[d]->siz;}return;} 17 }treap[maxn],*nodecnt=treap,*root;queue<node*>R; 18 void del(node*&x){R.push(x);x=NULL;return;} 19 void deltree(node*&x){ 20 if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return; 21 } 22 node*newnode(){ 23 node*k;if(R.empty())k=nodecnt++;else k=R.front(),R.pop();k->init();return k; 24 } 25 void rotate(node*&x,int d){ 26 node*k=x->ch[d^1];x->ch[d^1]=k->ch[d];k->ch[d]=x;x->update();k->update();x=k;return; 27 } 28 void insert(node*&x,int v){ 29 if(!x)x=newnode(),x->v=v; 30 else{int d=v>x->v;insert(x->ch[d],v); 31 if(x->r<x->ch[d]->r)rotate(x,d^1);else x->update(); 32 }return; 33 } 34 void print(node*x){ 35 if(!x)return;print(x->ch[0]);printf("%d ",x->v);print(x->ch[1]);return; 36 } 37 int find(node*x,int v){ 38 if(!x)return 0; 39 if(v==x->v)return v; 40 if(v>x->v)return max(x->v,find(x->ch[1],v)); 41 return find(x->ch[0],v); 42 } 43 struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj; 44 void add(int x,int y,int w){ 45 *ms=(ted){x,y,w,fch[x]};fch[x]=ms++; 46 *ms=(ted){y,x,w,fch[y]};fch[y]=ms++; 47 return; 48 } 49 int ans,k,t[maxn],cnt,f[maxn],CG,siz[maxn],size;bool vis[maxn]; 50 void findcg(int x,int fa){ 51 siz[x]=1;int mxs=0; 52 for(ted*e=fch[x];e;e=e->nxt){ 53 int v=e->y;if(v!=fa&&!vis[v]){ 54 findcg(v,x);siz[x]+=siz[v];mxs=max(mxs,siz[v]); 55 } 56 }f[x]=max(mxs,size-siz[x]);if(f[x]<f[CG])CG=x;return; 57 } 58 void dfs(int x,int fa,int dis){ 59 siz[x]=1;t[cnt++]=dis; 60 for(ted*e=fch[x];e;e=e->nxt){ 61 int v=e->y;if(v!=fa&&!vis[v])dfs(v,x,dis+e->w),siz[x]+=siz[v]; 62 }return; 63 } 64 void solve(int x){ 65 vis[x]=true;insert(root,0); 66 for(ted*e=fch[x];e;e=e->nxt){ 67 int v=e->y;if(!vis[v]){ 68 cnt=0;dfs(v,x,e->w); 69 for(int i=0;i<cnt&&t[i]<=k;i++)ans=max(ans,find(root,k-t[i])+t[i]); 70 for(int i=0;i<cnt;i++)insert(root,t[i]); 71 } 72 }deltree(root); 73 for(ted*e=fch[x];e;e=e->nxt){ 74 int v=e->y;if(!vis[v]){ 75 f[CG=0]=size=siz[v];findcg(v,x);solve(CG); 76 } 77 }return; 78 } 79 inline int read(){ 80 int x=0,sig=1;char ch=getchar(); 81 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 82 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 83 return x*=sig; 84 } 85 inline void write(int x){ 86 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 87 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 88 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 89 } 90 int n; 91 void init(){ 92 srand(time(0)); 93 n=read();k=read();int x,y; 94 for(int i=1;i<n;i++)x=read(),y=read(),add(x,y,read()); 95 f[CG=0]=size=n;findcg(1,0);solve(CG);write(ans); 96 return; 97 } 98 void work(){ 99 return; 100 } 101 void print(){ 102 return; 103 } 104 int main(){init();work();print();return 0;} 105 /* 106 5 8 107 1 2 2 108 2 3 7 109 1 4 3 110 4 5 4 111 */