和【宏律】有一点像,第一眼是二分+带权二分图匹配,实际上不需要。。
可以把所有边按照边权排序然后搞一搞,具体做法就是每次合并两个端点,然后把子树大小和权值也合并。直到某个子树的大小已经超过剩余权值,这条边就是我们需要求的答案。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h>
2 #include<algorithm>
3 #define it register int
4 #define il inline
5 using namespace std;
6 const int N=1000005;
7 int h[N],nxt[N],adj[N],w[N],fa[N],cnt[N],n,tot;
8 struct ky{
9 int l,r,num;
10 bool operator<(const ky&p)const{
11 return num<p.num;
12 }
13 }a[N];
14 il int fd(it x){
15 return fa[x]==x?x:fa[x]=fd(fa[x]);
16 }
17 il void fr(int &num){
18 num=0;char c=getchar();int p=1;
19 while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
20 while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
21 num*=p;
22 }
23 int main(){
24 fr(n);
25 for(it i=1;i<n;++i) fr(a[i].l),fr(a[i].r),fr(a[i].num);
26 sort(a+1,a+n);
27 for(it i=1;i<=n;++i) fr(w[i]),fa[i]=i,cnt[i]=1,tot+=w[i];
28 for(it i=1,t1,t2;i<n;++i){
29 t1=fd(a[i].l),t2=fd(a[i].r);
30 fa[t1]=t2,cnt[t2]+=cnt[t1],w[t2]+=w[t1];
31 if(cnt[t2]>tot-w[t2]) return printf("%d",a[i].num),0;
32 }
33 printf("%d",a[n-1].num);
34 return 0;
35 }