并不会打树的划分算法
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2){ p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=10005;
struct edge{
int u,v,next;
}G[N<<1];
int head[N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int n,m,K;
int val[N];
int mid;
int left[N],T[N];
#define V G[p].v
inline void dfs(int u,int fa){
int tot=0,cnt=0;
for (int p=head[u];p;p=G[p].next)
if (V!=fa){
dfs(V,u);
tot+=left[V]; cnt+=T[V];
}
if (tot+val[u]>=mid)
T[u]=cnt+1,left[u]=0;
else
T[u]=cnt,left[u]=tot+val[u];
}
inline bool check(int mid){
::mid=mid; cl(T); cl(left);
dfs(1,0);
return T[1]>=K;
}
int main(){
int iu,iv,maxv=0;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(K);
for (int i=1;i<=n;i++)
read(iu),read(iv),val[iu]=iv,maxv=max(maxv,iv);
for (int i=1;i<=m;i++)
read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum);
int L=0,R=maxv*n+1,MID;
while (L+1<R)
if (check(MID=(L+R)>>1))
L=MID;
else
R=MID;
printf("%d\n",L);
return 0;
}