[IOI2011]Race

race

点分治

  题目链接:https://www.luogu.org/problemnew/show/P4149;

  在点分治过程中维护一下当层最小值即可,dfs一遍判断 路径权值 为v(v<=k)的路径最小数量g[v];

  然后求下g[k-v]+g[v]的最小数量,更新下答案即可;

代码

  

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int M=200009;
 5 const int N=1000009;
 6 int n,k,num=0,tot=0,top=0,ans=1e9;
 7 int size,minn,rt;
 8 int head[M],b[M],g[N],p[M],c[M],siz[M],dep[M];
 9 struct P{int to,ne,w;}e[M<<1];
10 bool vis[M];
11 int read(){
12     int rex=0,f=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){rex=rex*10+ch-'0';ch=getchar();}
15     return rex*f;
16 }
17 void getrt(int u,int fa){
18     int ma=0;siz[u]=1;
19     for(int i=head[u];i;i=e[i].ne){
20         int v=e[i].to;if(v==fa||vis[v])continue;
21         getrt(v,u);
22         siz[u]+=siz[v];ma=max(ma,siz[v]);
23     }
24     ma=max(ma,size-siz[u]);
25     if(ma<minn){minn=ma,rt=u;}
26 }
27 void dfs(int u,int fa,int w){
28     if(w>k)return;
29     b[++tot]=w;dep[u]=dep[fa]+1;c[tot]=dep[u];
30     for(int i=head[u];i;i=e[i].ne){
31         int v=e[i].to;
32         if(v!=fa&&!vis[v])dfs(v,u,w+e[i].w);
33     }
34 }
35 void get(int u,int fa,int w){
36     tot=0;
37     dep[fa]=0;
38     dfs(u,fa,w);
39     for(int i=1;i<=tot;++i){
40         ans=min(ans,c[i]+g[k-b[i]]);
41         p[++top]=b[i];
42     }
43     for(int i=1;i<=tot;++i)g[b[i]]=min(g[b[i]],c[i]);
44 }
45 void work(int u){
46     vis[u]=1;top=0;
47     for(int i=head[u];i;i=e[i].ne){
48         int v=e[i].to;
49         if(!vis[v])get(v,u,e[i].w);
50     }
51     for(int i=1;i<=top;++i)g[p[i]]=1e9;
52     for(int i=head[u];i;i=e[i].ne){
53         int v=e[i].to;if(vis[v])continue;
54         minn=1e9,size=siz[u];
55         getrt(v,0);
56         work(rt);
57     }
58 }
59 int main(){
60     n=read(),k=read();
61     for(int i=1,u,v,w;i<n;++i){
62         u=read()+1,v=read()+1,w=read();
63         e[++num]=(P){v,head[u],w};head[u]=num;
64         e[++num]=(P){u,head[v],w};head[v]=num;
65     }
66     for(int i=1;i<=k;++i)g[i]=1e9;
67     minn=1e9,size=n;
68     getrt(1,0);
69     work(rt);
70     if(ans==1e9)ans=-1;
71     printf("%d",ans);
72     return 0;
73 }
View Code

 

  

posted @ 2018-11-26 22:57  sjie  阅读(138)  评论(0编辑  收藏  举报