51nod 1806 wangyurzee的树

来源:互联网 发布:语句sql2000创建数据库 编辑:程序博客网 时间:2024/06/05 19:08

要求度数不为某个数不好做,但是要求度数必须是某个数是可以直接算的。因为m比较小,暴力容斥就可以了。答案是

SU(n2)!iS(bi1)!(n2iS(bi1))!(n|S|)n2iS(bi1)[|S|&1?1:1]

#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int maxn=2000010,p=1000000007;int pow(int base,int k){    int ret=1;    for (;k;k>>=1,base=(LL)base*base%p)        if (k&1) ret=(LL)ret*base%p;    return ret;}int a[20],b[20],fac[maxn],inv[maxn],vis[20],n,m;int main(){    int ans=0,cnt,num,ok,tem;    scanf("%d%d",&n,&m);    if (n==1)    {        printf("1\n");        return 0;    }    for (int i=0;i<m;i++) scanf("%d%d",&a[i],&b[i]),a[i]--,b[i]--;    fac[0]=inv[0]=1;    for (int i=1;i<=n;i++) fac[i]=(LL)fac[i-1]*i%p;    inv[n]=pow(fac[n],p-2);    for (int i=n-1;i;i--) inv[i]=(LL)inv[i+1]*(i+1)%p;    for (int S=0;S<(1<<m);S++)    {        for (int i=0;i<m;i++) vis[i]=0;        cnt=num=0;        ok=1;        tem=fac[n-2];        for (int i=0;i<m;i++)            if ((S>>i)&1)            {                if (vis[a[i]])                {                    ok=0;                    break;                }                else vis[a[i]]=1;                cnt++;                num+=b[i];                tem=(LL)tem*inv[b[i]]%p;            }        if (!ok||num>n-2) continue;        tem=(LL)tem*inv[n-2-num]%p*pow(n-cnt,n-2-num)%p;        if (cnt&1) ans=(ans-tem+p)%p;        else ans=(ans+tem)%p;    }    printf("%d\n",ans);}