zoukankan      html  css  js  c++  java
  • SPOJ

    https://vjudge.net/problem/SPOJ-HIGH

    题意:

    给n个点m条边,求生成树个数。

     

    思路:

    矩阵树裸题。

    具体的话可以看一下周冬的论文《生成树的计数及其应用》。

    简单说一下,$A[ ][ ]$为邻接矩阵,有边为1(其实也就是边的个数,有重边时要注意),无边为0。$D[ ][ ]$为度数矩阵,$i=j$时为1,否则为0。

    $C[ ][ ]$为关联矩阵,$C[ ][ ]=D[ ][ ]-A[ ][ ]$。

    最后解任意n-1阶的主子式即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,ll> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn=1000+5;
    17 
    18 int n,m;
    19 double C[maxn][maxn];
    20 int A[maxn][maxn],D[maxn][maxn];
    21 
    22 double Gauss()
    23 {
    24     for(int k=1; k<=n; k++)  //k表示当前行数,因为行数与列数一样,所以这里k也代表了列数
    25     {
    26         int max_r=k;
    27         for(int i=k+1;i<=n;i++)
    28             if(fabs(C[i][k])>fabs(C[max_r][k]))  max_r=i;
    29         if(C[max_r][k]==0)  return 0;  //有一列为0,行列式的值必为0
    30         if(max_r!=k)
    31         {
    32             for(int j=k;j<=n;j++)
    33                 swap(C[k][j],C[max_r][j]);
    34         }
    35         for(int i=k+1;i<=n;i++)
    36         {
    37             double tmp=C[i][k]/C[k][k];
    38             for(int j=k;j<=n;j++)
    39                 C[i][j]-=tmp*C[k][j];
    40         }
    41     }
    42     double ans=1;
    43     for(int i=1;i<=n;i++)  ans*=C[i][i];  //化为三角阵后计算主对角线元素乘积
    44     ans=fabs(ans);
    45     return ans;
    46 }
    47 
    48 int main()
    49 {
    50     //freopen("in.txt","r",stdin);
    51     int T;
    52     scanf("%d",&T);
    53     while(T--)
    54     {
    55         memset(A,0,sizeof(A));
    56         memset(D,0,sizeof(D));
    57         scanf("%d%d",&n,&m);
    58         for(int i=0;i<m;i++)
    59         {
    60             int u,v;
    61             scanf("%d%d",&u,&v);
    62             D[u][u]++; D[v][v]++;
    63             A[u][v]++; A[v][u]++;
    64         }
    65         n--;
    66         for(int i=1;i<=n;i++)
    67         for(int j=1;j<=n;j++)
    68             C[i][j]=D[i][j]-A[i][j];
    69         printf("%.0lf
    ",Gauss());
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    treeview(树加载)
    9.SQL存储过程实例详解
    面向对象之封装
    cookie和session
    自定义web框架
    IO多路复用
    协程
    concurrent.futures模块(进程池/线程池)
    死锁与递归锁及信号量等
    并发编程之多线程
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7355969.html
Copyright © 2011-2022 走看看