BZOJ2599: [IOI2011]Race(点分治)

Description

给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000

Input

第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

解题思路:

点分治的时候开一个桶,记录边权值的大小,将两个童相加,更新最小值答案就行了。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 typedef long long lnt;
  5 const int N=200010;
  6 const int maxK=1000010;
  7 struct pnt{
  8     int hd;
  9     int wgt;
 10     int dis;
 11     bool vis;
 12 }p[N];
 13 struct ent{
 14     int twd;
 15     int lst;
 16     int vls;
 17 }e[N<<1];
 18 int n,K;
 19 int cnt;
 20 int ans;
 21 int size;
 22 int root;
 23 int maxsize;
 24 int has[maxK];
 25 void ade(int f,int t,int v)
 26 {
 27     cnt++;
 28     e[cnt].twd=t;
 29     e[cnt].lst=p[f].hd;
 30     e[cnt].vls=v;
 31     p[f].hd=cnt;
 32     return ;
 33 }
 34 void grc_dfs(int x,int f)
 35 {
 36     p[x].wgt=1;
 37     int maxs=-1;
 38     for(int i=p[x].hd;i;i=e[i].lst)
 39     {
 40         int to=e[i].twd;
 41         if(to==f||p[to].vis)
 42             continue;
 43         grc_dfs(to,x);
 44         p[x].wgt+=p[to].wgt;
 45         if(maxs<p[to].wgt)
 46             maxs=p[to].wgt;
 47     }
 48     maxs=std::max(maxs,size-p[x].wgt);
 49     if(maxs<maxsize)
 50     {
 51         maxsize=maxs;
 52         root=x;
 53     }
 54     return ;
 55 }
 56 void update(int x,int f,int dep)
 57 {
 58     if(p[x].dis<=K)
 59         has[p[x].dis]=std::min(has[p[x].dis],dep);
 60     for(int i=p[x].hd;i;i=e[i].lst)
 61     {
 62         int to=e[i].twd;
 63         if(to==f||p[to].vis)
 64             continue;
 65         update(to,x,dep+1);
 66     }
 67     return ;
 68 }
 69 void clear(int x,int f)
 70 {
 71     if(p[x].dis<=K)
 72         has[p[x].dis]=0x3f3f3f3f;
 73     for(int i=p[x].hd;i;i=e[i].lst)
 74     {
 75         int to=e[i].twd;
 76         if(to==f||p[to].vis)
 77             continue;
 78         clear(to,x);
 79     }
 80     return ;
 81 }
 82 void ans_dfs(int x,int f,int dep)
 83 {
 84     if(p[x].dis<=K)
 85         ans=std::min(ans,dep+has[K-p[x].dis]);
 86     for(int i=p[x].hd;i;i=e[i].lst)
 87     {
 88         int to=e[i].twd;
 89         if(to==f||p[to].vis)
 90             continue;
 91         p[to].dis=p[x].dis+e[i].vls;
 92         ans_dfs(to,x,dep+1);
 93     }
 94     return ;
 95 }
 96 void bin_dfs(int x)
 97 {
 98     p[x].vis=true;
 99     has[0]=0;
100     for(int i=p[x].hd;i;i=e[i].lst)
101     {
102         int to=e[i].twd;
103         if(p[to].vis)
104             continue;
105         p[to].dis=e[i].vls;
106         ans_dfs(to,to,1);
107         update(to,to,1);
108     }
109     for(int i=p[x].hd;i;i=e[i].lst)
110     {
111         int to=e[i].twd;
112         if(p[to].vis)
113             continue;
114         clear(to,to);
115     }
116     for(int i=p[x].hd;i;i=e[i].lst)
117     {
118         int to=e[i].twd;
119         if(p[to].vis)
120             continue;
121         root=0;
122         size=p[to].wgt;
123         maxsize=0x3f3f3f3f;
124         grc_dfs(to,to);
125         bin_dfs(root);
126     }
127     return ;
128 }
129 int main()
130 {
131     scanf("%d%d",&n,&K);
132     memset(has,0x3f,sizeof(has));
133     has[0]=0;
134     for(int i=1;i<n;i++)
135     {
136         int a,b,c;
137         scanf("%d%d%d",&a,&b,&c);
138         a++,b++;
139         ade(a,b,c);
140         ade(b,a,c);
141     }
142     ans=0x3f3f3f3f;
143     root=0;
144     size=n;
145     maxsize=0x3f3f3f3f;
146     grc_dfs(1,1);
147     bin_dfs(root);
148     if(ans>=0x3f3f3f3f)
149         ans=-1;
150     printf("%d\n",ans);
151     return 0;
152 }

猜你喜欢

转载自www.cnblogs.com/blog-Dr-J/p/10159481.html