zoukankan      html  css  js  c++  java
  • 【中山市选2010】【BZOJ2467】生成树

    Description

    有一种图形叫做五角形圈。一个五角形圈的中心有1个由n个顶点和n条边组成的圈。

    在中心的这个n边圈的每一条边同一时候也是某一个五角形的一条边,一共同拥有n个不同的五角形。这些五角形仅仅在五角形圈的中心的圈上有公共的顶点。如图0所看到的是一个4-五角形圈。
    这里写图片描写叙述

    如今给定一个n五角形圈。你的任务就是求出n五角形圈的不同生成树的数目。还记得什么是图的生成树吗?一个图的生成树是保留原图的全部顶点以及顶点的数目减去一这么多条边,从而生成的一棵树。
    注意:在给定的n五角形圈中全部顶点均视为不同的顶点。


    Input

    输入包括多组測试数据。

    第一行包括一个正整数T,表示測试数据数目。每组測试数据包括一个整数n( 2<=N<=100),代表你须要求解的五角形圈中心的边数。

    Output

    对每一组測试数据,输出一行包括一个整数x。表示n五角形圈的生成树数目模2007之后的结果。
    Sample Input

    1

    2

    Sample Output

    40
    HINT

    Source

    直接Matrix-tree定理就好了
    也能够用组合数学/DP来做
    关于组合数学能够看PoPoQQQ的blog
    果然还是矩阵树好想…

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAXN 1010
    #define P 2007
    using namespace std;
    int A[MAXN][MAXN],D[MAXN][MAXN],C[MAXN][MAXN];
    int n,top;
    int T;
    int calc(int size)
    {
        for (int i=1;i<size;i++)
            for (int j=1;j<size;j++)
                C[i][j]=(C[i][j]+P)%P;
        int ret=1;
        for (int i=1;i<size;i++)
        {
            for (int j=i+1;j<size;j++)
            {
                int a=C[i][i],b=C[j][i];
                while (b)
                {
                    int temp=a/b;a%=b;swap(a,b);
                    for (int k=i;k<size;k++)    C[i][k]=(C[i][k]-temp*C[j][k])%P;
                    for (int k=i;k<size;k++)    swap(C[i][k],C[j][k]);
                    ret=-ret;
                }
            }
            if (!C[i][i])   return 0;
            ret=ret*C[i][i]%P;
        }
        return (ret+P)%P;
    }
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            memset(A,0,sizeof(A));memset(D,0,sizeof(D));
            scanf("%d",&n);
            top=n;
            for (int i=1;i<=n;i++)
            {
                int u=i,v=i+1>n?1:i+1;
                A[u][top+1]++;A[top+1][u]++;D[u][u]++;D[top+1][top+1]++;
                A[top+1][top+2]++;A[top+2][top+1]++;D[top+1][top+1]++;D[top+2][top+2]++;
                A[top+2][top+3]++;A[top+3][top+2]++;D[top+2][top+2]++;D[top+3][top+3]++;
                A[top+3][v]++;A[v][top+3]++;D[top+3][top+3]++;D[v][v]++;
                top+=3;
                A[u][v]++;A[v][u]++;D[u][u]++;D[v][v]++;
            }
            for (int i=1;i<=top;i++)
                for (int j=1;j<=top;j++)
                    C[i][j]=D[i][j]-A[i][j];
            cout<<calc(top)<<endl;
        }
    }
  • 相关阅读:
    regulation
    Java第三方类库
    python整个小服务器
    VsFTP出现500 OOPS: cannot change directory的解决办法
    Got error 28 from storage engine
    linux下ftp操作
    linux安装JDK
    Apache + Tomcat + Linux 集群和均衡负载 (Session 同步复制) 配置实
    怎么样才能使得PL/SQL Developer不显示系统表?
    sudo 用法
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7083236.html
Copyright © 2011-2022 走看看