zjuoj 3604 Tunnel Network

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3604

Tunnel Network

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Country Far-Far-Away is a big country with N cities. But it is now under a civil war. The rebel uses the ancient tunnel network which connects all N cities with N-1 inter-city tunnels for transportation. The government army want to destroy these tunnels one by one. After several months fighting, some tunnels have been destoryed. According to the intel, the tunnel network have excatly S connected components now. And what government army further knows is that city 1, 2, ... , S belong to each of the S connected components. Since the government have little knowledge about the remaining tunnels, they ask you to calculate the number of possible networks of remaining tunnels.

Input

There are multiple test cases. The first line of input contains an integer T (T ≤ 500) indicating the number of test cases. Then T test cases follow.

Each case contains one line containing two integer N (2 ≤ N ≤ 2000) and S (2 ≤ S ≤ N), as described above.

Output

The number of possible networks now. Since the number might be very large, you should output the answer after modulo 1000000007.

Sample Input

4
3 2
4 2
5 3
100 50

Sample Output

2
8
15
113366355

Author: WANG, Yelei
Contest: The 9th Zhejiang Provincial Collegiate Programming Contest

分析:

  不过对于给定的n和s,可以对n-s个点先排列然后划分成s份,然后计算有x个点树有多少种。这样显然不好递推,也没法写公式。事实上对任意n个点构成的树对应一个长为n-2的Prufer序列,且这种关系是一一对应。所谓Prufer序列是每次拿掉编号最小的叶节点然后将它的父亲push,直到只剩下两个节点。因此可以假定有点0与s个城市分别相连,问题转化为这n+1个点构成的树的Prufer序列有多少种。注意到序列倒数第s个数必为1~s中的某一个且最后s-1个数必为根节点0,于是排列数为n^(n-s-1)*s。

prufer序列:http://www.cnblogs.com/jeff-wgc/p/4472528.html

AC代码:

 1 #include <cstdio>
 2 #define Mod 1000000007
 3 
 4 int T, s, t;
 5 long long n, r;
 6 
 7 inline int cal()
 8 {
 9     if(n == s) return 1;
10     t = n-s-1, r = s;
11     while(t > 0)
12     {
13         if(t&1) r=(r*n)%Mod;
14         t >>=1, n=(n*n)%Mod;
15     }
16     return r;
17 }
18 
19 int main()
20 {
21     scanf("%d", &T);
22     while(T --)
23     {
24         scanf("%d%d", &n, &s);
25         printf("%d
", cal());
26     }
27     return 0;
28 }
View Code
原文地址:https://www.cnblogs.com/jeff-wgc/p/4472519.html