zoukankan      html  css  js  c++  java
  • CF917D Stranger Trees【矩阵树定理,高斯消元】

    题目链接:洛谷

    题目大意:给定一个$n$个节点的树$T$,令$ans_k=sum_{T'}[|Tcap T'|=k]$,即有$k$条边重合。输出$ans_0,ans_1,ldots,ans_{n-1}$.

    数据范围:$1leq nleq 100$


    这题的思路挺巧妙的,非常不错。

    我们将$T$上的边的边权作为$x$,不在$T$上的边的边权设为$1$(一个完全图),然后用矩阵树定理算出所有生成树的边权之积之和,也就是$x^k$的系数就是$ans_k$,现在我们要求这个多项式。

    但是运算一个多项式的行列式复杂度会高到爆炸,所以我们考虑插值,只需要$n$个点值就可以,这里我们取$x=1,2,ldots n$,然后用高斯消元算出这个多项式的系数就可以。(具体实现看代码)

    时间复杂度$O(n^4)$。

     1 #include<bits/stdc++.h>
     2 #define Rint register int
     3 using namespace std;
     4 typedef long long LL;
     5 const int N = 103, mod = 1e9 + 7;
     6 int n, a[N][N], b[N][N];
     7 bool tree[N][N];
     8 inline int kasumi(int a, int b){
     9     int res = 1;
    10     while(b){
    11         if(b & 1) res = (LL) res * a % mod;
    12         a = (LL) a * a % mod;
    13         b >>= 1;
    14     }
    15     return res;
    16 }
    17 inline int Gauss(){
    18     int res = 1;
    19     for(Rint i = 1;i < n;i ++){
    20         for(Rint j = i + 1;j < n;j ++)
    21             while(a[j][i]){
    22                 int d = a[i][i] / a[j][i];
    23                 for(Rint k = i;k < n;k ++)
    24                     a[i][k] = (a[i][k] - (LL) d * a[j][k] + mod) % mod;
    25                 swap(a[i], a[j]);
    26                 res = mod - res;
    27             }
    28         res = (LL) res * a[i][i] % mod;
    29         if(!a[i][i]) return 0;
    30     }
    31     return res;
    32 }
    33 int main(){
    34     scanf("%d", &n);
    35     for(Rint i = 1;i < n;i ++){
    36         int a, b;
    37         scanf("%d%d", &a, &b);
    38         tree[a][b] = tree[b][a] = true;
    39     }
    40     for(Rint k = 1;k <= n;k ++){
    41         for(Rint i = 1;i <= n;i ++){
    42             a[i][i] = 0;
    43             for(Rint j = 1;j <= n;j ++){
    44                 if(i != j){
    45                     if(tree[i][j]){
    46                         a[i][j] = mod - k;
    47                         a[i][i] = (a[i][i] + k) % mod;
    48                     } else {
    49                         a[i][j] = mod - 1;
    50                         a[i][i] = (a[i][i] + 1) % mod;
    51                     }
    52                 }
    53             }
    54         }
    55         b[k][1] = 1;
    56         for(Rint i = 2;i <= n;i ++) b[k][i] = (LL) b[k][i - 1] * k % mod;
    57         b[k][n + 1] = Gauss();
    58     }
    59     for(Rint i = 1;i <= n;i ++){
    60         int inv = kasumi(b[i][i], mod - 2);
    61         for(Rint j = i + 1;j <= n + 1;j ++)
    62             b[i][j] = (LL) b[i][j] * inv % mod;
    63         for(Rint j = 1;j <= n;j ++)
    64             if(i != j)
    65                 for(Rint k = i + 1;k <= n + 1;k ++)
    66                     b[j][k] = (b[j][k] - (LL) b[j][i] * b[i][k] % mod + mod) % mod;
    67     }
    68     for(Rint i = 1;i <= n;i ++) printf("%d ", b[i][n + 1]);
    69 }
    CF917D
  • 相关阅读:
    CSS 样式清单整理
    JavaScript常用方法封装
    c# 异常:值不能为 null。 参数名: source
    iframe重新加载
    jquery 获取 父级 iframe 里的控件对象
    添加外键约束
    LinQ to entities 不能识别方法“system.string.ToString(system.String)”.因此该方法无法转换为存储表达式
    c# pcm
    .Net Core 2.0 App中读取appsettings.json
    c# 泛型demo
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/10962738.html
Copyright © 2011-2022 走看看