zoukankan      html  css  js  c++  java
  • BZOJ 1002: [FJOI2007]轮状病毒【生成树的计数与基尔霍夫矩阵简单讲解+高精度】

    1002: [FJOI2007]轮状病毒

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 5577  Solved: 3031
    [Submit][Status][Discuss]

    Description

      轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
    和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

      N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
    同的3轮状病毒,如下图所示

      现给定n(N<=100),编程计算有多少个不同的n轮状病毒

    Input

      第一行有1个正整数n

    Output

      计算出的不同的n轮状病毒数输出

    Sample Input

    3

    Sample Output

    16

    HINT

    Source

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1002

    关于基尔霍夫矩阵:

    *算法引入:
    *给定一个无向图G,求它生成树的个数t(G);
    *
    *算法思想:
    *(1)G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数;
    *(2)G的邻接矩阵A[G]是一个n*n的矩阵,并且满足:如果vi,vj之间有边直接相连,则aij=1,否则为0;
    *定义图G的Kirchhoff矩阵C[G]为C[G]=D[G]-A[G];
    *Matrix-Tree定理:G的所有不同的生成树的个数等于其Kirchhoff矩阵C[G]任何一个n-1阶主子式的行列式的绝对值;
    *所谓n-1阶主子式,就是对于r(1≤r≤n),将C[G]的第r行,第r列同时去掉后得到的新矩阵,用Cr[G]表示;

    此题推出f[i]=(f[i-1]*3-f[i-2]+2)

    下面给出AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 inline int read()
     5 {
     6     int x=0,f=1;
     7     char ch=getchar();
     8     while(ch<'0'||ch>'9')
     9     {
    10         if(ch=='-')
    11             f=-1;
    12         ch=getchar();
    13     }
    14     while(ch>='0'&&ch<='9')
    15     {
    16         x=x*10+ch-'0';
    17         ch=getchar();
    18     }
    19     return x*f;
    20 }
    21 inline void write(int x)
    22 {
    23     if(x<0)
    24     {
    25         putchar('-');
    26         x=-x;
    27     }
    28     if(x>9)
    29     {
    30         write(x/10);
    31     }
    32     putchar(x%10+'0');
    33 }
    34 struct data
    35 {
    36     int a[101],len;
    37 };
    38 int n;
    39 data mul(data a,int k)
    40 {
    41     for(int i=1;i<=a.len;i++)
    42         a.a[i]*=k;
    43     for(int i=1;i<=a.len;i++)
    44     {
    45         a.a[i+1]+=a.a[i]/10;
    46         a.a[i]%=10;
    47     }
    48     if(a.a[a.len+1]!=0)
    49         a.len++;
    50     return a;
    51 }
    52 data sub(data a,data b)
    53 {
    54     a.a[1]+=2;
    55     int j=1;
    56     while(a.a[j]>=10)
    57     {
    58         a.a[j]%=10;
    59         a.a[j+1]++;
    60         j++;
    61     }
    62     for(int i=1;i<=a.len;i++)
    63     {
    64         a.a[i]-=b.a[i];
    65         if(a.a[i]<0)
    66         {
    67             a.a[i]+=10;
    68             a.a[i+1]--;
    69         }
    70     }
    71     while(a.a[a.len]==0)
    72         a.len--;
    73     return a;
    74 }
    75 int main()
    76 {
    77     data f[101];f[1].a[1]=1;f[2].a[1]=5;
    78     f[1].len=f[2].len=1;
    79     n=read();
    80     for(int i=3;i<=n;i++)
    81         f[i]=sub(mul(f[i-1],3),f[i-2]);
    82     for(int i=f[n].len;i>0;i--)
    83        write(f[n].a[i]);
    84     return 0;
    85 }
  • 相关阅读:
    PHP数组处理总结
    设计模式之-工厂模式理解
    我的世界观
    编程入门
    2019 新的一年
    placeholder 不支持ie8
    2018年8月20日
    HttpClientUtil
    通用mapper
    small_demo
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/7412930.html
Copyright © 2011-2022 走看看