P5021 track construction
analysis:
It is clear to a half value.
For the relationship between a track and a point u can be divided into three cases:
1. entirely within a subtree u. 2. subtree in half, the outer half of the subtree 3. After u, the other strand is connected to the subtree
In the first case, directly in the recursion when he included contributions.
For the second three cases, open a multiset, encountered no legal value is placed in the multiset.
Back each time, the first sub-tree can twenty-two combined merged, and not twenty-two combined, takes a maximum left to match its parent node.
multiset There are a lot of details:
1. erase can either delete a value, you can also delete a location! !
2. Delete the order is important, do not delete after a point, and that point to point, point to empty this time, resulting in a crash.
#include<bits/stdc++.h> using namespace std; #define ri register int #define N 50005 int head[N],nex[N<<1],to[N<<1],tot=0,w[N<<1],n,m,mid,ans; void add(int a,int b,int ww) { tot++; to[tot]=b; nex[tot]=head[a]; head[a]=tot; w[tot]=ww; } multiset<int> st[N]; multiset<int>::iterator it;//!!!在外面定义才能遍历完 int dfs(int u,int ff) { st[u].clear(); int val; for(ri i=head[u];i;i=nex[i]){ int v=to[i]; if(v==ff) continue; val=dfs(v,u)+w[i]; if(val>=mid) ans++;//子树内的链直接满足情况,就ans++ else st[u].insert(val); } int mx=0; while(!st[u].empty()){ if(st[u].size()==1) return mx=max(mx,*st[u].begin()); ITST = [U] .lower_bound (mid- ST * [U] .begin ()); // find the position corresponding IF (ST [U] .begin () && == IT ST [U] .count (IT * ) == . 1 ) iT ++; // if found themselves skipped // if the value does not exist the corresponding paired with it, that it is too small, to delete this value IF (ST iT == [U]. End ()) = max MX (MX, ST * [U] .begin ()), ST [U] .erase (ST * [U] .begin ()); // Note that the value of the delete! ! the else { // otherwise will be paired with a corresponding position ANS ++ ; // NOTE sequence: first to delete it, or after deleting begin, if it points to begin, then it will point to an empty, will explode st [u] .erase ( IT); ST [U] .erase (ST [U] .begin ()); // this is the head position of the deletion, and should not be a value, because there are multiple values, the position of only one } } return mx; } int main() { scanf("%d%d",&n,&m); int sum=0,a,b,ww; for(ri i=1;i<=n-1;++i) scanf("%d%d%d",&a,&b,&ww),add(a,b,ww),add(b,a,ww),sum+=ww; int l=0,r=sum+1,anss=0; while(l<r){ mid=(l+r)>>1; ans=0; dfs(1,0); if(ans<m) r=mid; else l=mid+1,anss=mid; } printf("%d\n",anss); }