题目:
2 9 2 1 3 1 4 3 5 3 6 2 7 4 8 7 9 3 8 2 1 3 1 4 3 5 1 6 4 7 5 8 4
Case #1: 32 Case #2: 16
题意:给一固定形态的树,有n个节点,现在要给这n个节点赋值,每个节点取1到n的某个数,不能重复,并且满足:1.任意节点的所有子节点的值必须连续 2.任意节点的子树的值必须连续。 问有多少种赋值方法。
思路:由于这两条规则的限制,不能有超过两个非叶子节点,并且非叶子节点一定是取连续区间的端点。这样的话非叶子节点有两种取法,剩下的叶子节点有k!种取法,因为顺序是任意的。所以对于某个根节点而言,它如果有孩子,那么首先他有两种取法,可以取区间最大或最小值,然后孩子中的叶子节点有k!取法,非叶节点再dfs下去求。
代码:
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include<climits>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
#define PB push_back
#define MP make_pair
#define REP(i,x,n) for(int i=x;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define OI(X) printf("%d",X);
#define RS(X) scanf("%s", (X))
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define Dpoint strcut node{int x,y}
#define cmpd int cmp(const int &a,const int &b){return a>b;}
/*#ifdef HOME
freopen("in.txt","r",stdin);
#endif*/
const int MOD = 1e9+7;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long LL;
typedef pair<int,int> PII;
//#define HOME
int Scan()
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
/*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/
#define MAXN 100000
const int mod=1e9+7;
vector<int>g[MAXN+5];
int sz[MAXN+5];
int fact[MAXN+5];
int dfs(int u,int f)
{
int ans=1;
sz[u]=1;
int son1=0;
int son2=0;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==f)
continue;
ans=((long long)ans*dfs(v,u))%mod;
if(sz[v]>1)
son2++;
else
son1++;
sz[u]+=sz[v];
}
if(son2>2)
return 0;
if(son2!=0)
ans=((long long)ans*2)%mod;
ans=((long long )ans*fact[son1])%mod;
return ans;
}
int main()
{int T;
RI(T);
fact[0]=1;
for(int i=1;i<=MAXN;i++)
fact[i]=((long long )fact[i-1]*i)%mod;
for(int t=1;t<=T;t++)
{
int n;
RI(n);
for(int i=0;i<=n;i++)
g[i].clear();
for(int i=0;i<n-1;i++)
{
int u,v;
RII(u,v);
g[u].push_back(v);
g[v].push_back(u);
}
MS0(sz);
int ans=dfs(1,0);
if(sz[1]>1)
ans=((long long )ans*2)%mod;
printf("Case #%d: %d\n",t,ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013840081/article/details/48012323