• 1002: [FJOI2007]轮状病毒


    题目链接:

    题意:就是给出n,表示有n+1个点通过n条边相连。求一共有多少种连法!总的来说就是求生成树的个数有多少种

    这是一篇大佬的题解:

    其实说了一大堆就是证明了f[i]=3f[i-1]-f[i-2]+2。这个就是本题的递推式

    而这个怎么来的?大佬的证明说明了一个基尔霍夫矩阵的任一余子式的行列式的值就是该图的生成树的个数 

    所以我们就可以通过对余子式做代数余子式的展开求行列式的方法,就可以推出上面那个公式,不会推就记住好了(反正我觉得我就算现在会推过几天就忘了emmm)

    本题虽然最大数据只有100,但是还是顶不住爆ll,所以要写个高精度加法跟减法,那个乘法相当于加三次(我不想敲高精度乘法,主要是不太会)

    #include <set>
    #include <map>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <iostream>
    #include <functional>
    using namespace std;
    #define ll long long
    #define fi first
    #define se second
    #define re register
    #define pb push_back
    void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch-'0';
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=a*10+ch-'0';
        a*=d;
    }
    void write(int x)
    {
        if(x<0)
            putchar(45),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    string f[105];
    string add(string st1,string st2)
    {
        string str;
        int d=0;
        int len1=st1.length();
        int len2=st2.length();
        if(len1>len2)
            for(re int i=0;i<len1-len2;i++)
                st2='0'+st2;
        else
            for(re int i=0;i<len2-len1;i++)
                st1='0'+st1;
        for(re int i=st1.size()-1;i>=0;i--)
        {
            int a,b;
            a=st1[i]-'0';
            b=st2[i]-'0';
            a=a+b+d;
            d=a/10;
            str=char(a%10+'0')+str;
        }
        if(d!=0)  str=char(d+'0')+str;
        return str;
    }
    string solve(int x)
    {
        string s="";
        do
        {
            s.pb(x%10);
            x/=10;
        }while(x);
        reverse(s.begin(),s.end());
        return s;
    }
    string sub(string st1,string st2)
    {
        string tem;
        int d=0;
        bool f=true;
        int len1=st1.length();
        int len2=st2.length();
        if(len1<len2||(len1==len2&&st1<st2))
        {
            string t=st1;
            st1=st2;
            st2=t;
            int tt=len1;
            len1=len2;
            len2=tt;
            f=false;
        }
        else if(len1==len2&&st1==st2)
        {
            tem='0';
            return tem;
        }
        for(re int i=1;i<=len1-len2;i++)
            st2='0'+st2;
        for(re int i=len1-1;i>=0;i--)
        {
            int t=(st1[i]-'0')-(st2[i]-'0')-d;
            if(t<0)
            {
                t+=10;
                d=1;
            }
            else
                d=0;
            tem=char(t+'0')+tem;
        }
        if(tem.size()==1)
        {
            if(!f)
                tem='-'+tem;
            return tem;
        }
        while(1)
        {
            if(tem[0]=='0')
                tem.erase(0,1);
            else
                break;
        }
        if(!f)
            tem='-'+tem;
        return tem;
    }
    int main()
    {
        int n;read(n);
        string st1,st2;
        f[1]="1",f[2]="5";
        st1=solve(n);st2=solve((n+1)*n);
        for(re int i=3;i<=n;i++)
        {
            for(re int j=1;j<=3;j++) f[i]=add(f[i],f[i-1]);
            f[i]=add(f[i],"2");
            f[i]=sub(f[i],f[i-2]);
        }
        cout<<f[n]<<endl;
        return 0;
    }
  • 相关阅读:
    Android笔记之添加退出确认对话框
    Android笔记之menu与ActionBar使用
    Android学习笔记之File存储(sd卡)
    cron 在线 表达式
    springboot
    mybatis 查询标签
    div display 常用属性
    css height VS min-height
    struts标签 解析html标签
    CSS 后代选择器
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/12019327.html
Copyright © 2020-2023  润新知