Treecnt
Base time limit: 1 seconds space limit: 131072 KB
A tree of n nodes, numbered from 1 to N. Choose K points, you need to select some edge to make this k point through the selected side of the link, the goal is to make the selected number of sides the least.
It is now necessary to calculate the sum of the minimum number of selected edges for all selected K points.
Sample explanation:
There are three possibilities: (The following blue dots indicate the selected point, and the red edge represents the edge in the optimal scheme)
Select Point {min}: Select at least the first edge to make 1 and 2 unicom.
Select Point {1,3}: Select at least the second edge to make 1 and 3 unicom.
Select Point {2,3}: two edges to choose to make 2 and 3 unicom.
Input
First row two number N,k (1<=k<=n<=100000) Next n-1 line, two numbers per line x, Y describes an edge (1<=x,y<=n)
Output
A number, the answer to 1,000,000,007 modulo.
Input example
3 21 21 3
Output example
4
Idea: Consider the contribution of each side.
One side divides a tree into two parts, and when this side contributes, the k points must be distributed in two parts that are separated by this side.
The total number of cases equals C (n,k), the number of points is X, the other part is n-x, the illegal case is equal to C (x,k) +c (n-x,k); and then the solution is to go.
Find the number of points on both sides of the edge, then we have a point for the root Dfs to find the degree of the sub-tree of each point, and then traverse each edge, then the current two points, the degree of small is necessarily another subtree, then X is found out.
Complexity o (n);
1#include <stdio.h>2#include <algorithm>3#include <iostream>4#include <string.h>5#include <math.h>6#include <queue>7#include <stdlib.h>8#include <Set>9#include <vector>TentypedefLong LongLL; One using namespacestd; Atypedefstructnode - { - intx; the inty; - } SS; -SS ans[100005]; -vector<int>vec[100005]; + intcnt[100005]; - BOOLflag[100005]; + intDfsintn); ALL n[100005]; at ConstLL mod = 1e9+7; - ll Quick (ll n,ll m); - intMainvoid) - { - intn,k,i; -n[0] =1; in for(i =1; I <=100000; i++) - { toN[i] = n[i-1]* (LL) i%MoD; + } - while(SCANF ("%d%d", &n,&k)! =EOF) the { * //int i; $memset (CNT,0,sizeof(CNT));Panax Notoginsengmemset (Flag,0,sizeof(flag)); - for(i =0; I <= N; i++) the vec[i].clear (); + for(i =0; I < n1; i++) A { thescanf"%d%d",&ans[i].x,&ans[i].y); + Vec[ans[i].x].push_back (ANS[I].Y); - Vec[ans[i].y].push_back (ans[i].x); $ } $Dfs1); -LL ni = n[n-k]*n[k]%MoD; -NI = Quick (ni,mod-2); theLL sum = n[n]*ni%MoD; -sum = sum* (n1)%MoD;Wuyi for(i =0; I < n1; i++) the { - intx =cnt[ans[i].x]; Wu inty =CNT[ANS[I].Y]; - intAA =min (x, y); About intBB = nAA; $ if(AA >=k) - { -LL xx = n[aa-k]*n[k]%MoD; -NI = Quick (xx,mod-2); ANI = n[aa]*ni%MoD; +sum = Sum-ni; thesum = (sum%mod) +MoD; -sum%=MoD; $ } the if(BB >=k) the { theLL xx = n[bb-k]*n[k]%MoD; theNI = Quick (xx,mod-2); -NI = N[bb]*ni%mod;//printf ("%lld\n", ni); insum = Sum-ni; thesum = (sum%mod) +MoD; thesum%=MoD; About } the } theprintf"%lld\n", sum); the } + } - intDfsintN) the {BayiFlag[n] =true; the inti; the for(i =0; I < vec[n].size (); i++) - { - intx =Vec[n][i]; the if(!Flag[x]) the { thecnt[n]+=dfs (x); the } - } thecnt[n]++; the returnCnt[n]; the }94 ll Quick (ll n,ll m) the { theLL Ask =1; then%=MoD;98 while(m) About { - if(m&1)101Ask = ask*n%MoD;102n = n*n%MoD;103m>>=1;104 } the returnask;106}
TREECNT algorithm Marathon 20 (farewell to US election and Castro)