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
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 ",ans); 151 return 0; 152 }