链接:https://www.nowcoder.com/acm/contest/203/H
来源:牛客网
题目描述
魔方国有n座城市,编号为。城市之间通过n-1条无向道路连接,形成一个树形结构。
澜澜打算在魔方国进行m次旅游,每次游览至少一座城市。为了方便,每次旅游游览的城市必须是连通的。此外,澜澜希望游览所有城市恰好一次。
澜澜想知道有多少种旅游方案满足条件,两个方案不同当且仅当存在某一次旅游游览了不同的城市。
澜澜不会数数,所以只好让你来帮他数方案。
输入描述:
第一行一个整数t表示数据组数 (1 ≤ t ≤ 100)。
每组数据第一行两个整数n,m ,接下来n-1行每行两个整数ai,bi表示一条道路 (1≤ ai,bi≤ n)。
输出描述:
每组数据输出一行一个整数表示方案数对109+7取模的结果。
示例1
输入
复制
2
3 1
1 2
1 3
3 2
1 2
1 3
输出
复制
1
4

这题算是比较有成就感的一题,差不多花了一个小时,整理一下思路
一开始我就是直接直接看,然后手算出发现同个图不同的构造的在m不等于1的情况下方案数是一样的,然后队友过来帮忙组合数推了一下发现n等于3和4的情况确实如此,虽然和我手算的不一样,然后就推了一下5,就发现确实可以用组合数来算,比如n个点的情况,m次旅游的方案就是C的n-1取m-1乘以A的m取m,为什么这样呢,其实就是把n个点看成一条链,然后用插空法,然后分成的m份再全排列,然后约分一下就可以得到最后的公式了,边乘边取模,然后注意特判1

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int MOD=1e9+7;
int t;
int n,m;
int a,b;
int deg[N*2];
int main(void){
   
    scanf("%d",&t);
    while(t--){
   
        int maxD=0;
        memset(deg,0,sizeof(deg));
        scanf("%d%d",&n,&m);
        for(int i=0;i<n-1;i++){
   
            scanf("%d%d",&a,&b);
            deg[a]++;
            deg[b]++;
            maxD=max(maxD,max(deg[a],deg[b]));
        }
        //非链
        if(maxD>2 && m==1){
   
            printf("0\n");
        }
        else{
   
            ll ans=m;
            for(ll i=n-1;i>=n-m+1;i--){
   
                ans=(ans*i)%MOD;
            }
            printf("%lld\n",ans);
        }
    }
}