zoukankan      html  css  js  c++  java
  • UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=648&page=show_problem&problem=5150

    题目大意:给一幅N个点M条边的无向图,有一些边,其中一部分只能涂红色,一部分只能涂黑色,一部分两种颜色都可以涂。现要求红色的边不超过K条的生成树个数模1e9+7的值。

    思路:感谢昂神滋磁,贴链接:http://sd-invol.github.io/2015/05/31/Matrix-Tree-Polynomial/

    由于不会范德蒙德矩阵,也不会拉格朗日插值,只好乖乖高斯消元了……

    代码(0.429S):

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <vector>
      6 using namespace std;
      7 typedef long long LL;
      8 typedef vector<vector<int> > Mat;
      9 
     10 const int MAXV = 55;
     11 const int MAXE = MAXV * MAXV;
     12 const int MOD = 1e9 + 7;
     13 
     14 void debug(const Mat &a) {
     15     puts("#debug:");
     16     for(auto &i : a) {
     17         for(auto j : i) printf("%d ", j);
     18         puts("");
     19     }
     20 }
     21 
     22 int inv(int x) {
     23     if(x == 1) return 1;
     24     return LL(MOD - MOD / x) * inv(MOD % x) % MOD;
     25 }
     26 
     27 int det(Mat &a, int n) {
     28     LL res = 1;
     29     for(int i = 1; i < n; ++i) {
     30         if(a[i][i] == 0) return 0;
     31         for(int j = i + 1; j < n; ++j) {
     32             LL t = LL(a[j][i]) * inv(a[i][i]) % MOD;
     33             for(int k = i; k < n; ++k) {
     34                 a[j][k] -= (a[i][k] * t) % MOD;
     35                 if(a[j][k] < 0) a[j][k] += MOD;
     36             }
     37         }
     38         res = (res * a[i][i]) % MOD;
     39     }
     40     return res;
     41 }
     42 
     43 void guass(Mat &a, int n) {
     44     for(int i = 0; i < n; ++i) {
     45         for(int j = i + 1; j < n; ++j) {
     46             LL t = LL(a[j][i]) * inv(a[i][i]) % MOD;
     47             for(int k = i; k <= n; ++k) {
     48                 a[j][k] -= (a[i][k] * t) % MOD;
     49                 if(a[j][k] < 0) a[j][k] += MOD;
     50             }
     51         }
     52     }
     53     for(int i = n - 1; i >= 0; --i) {
     54         for(int j = i + 1; j < n; ++j) {
     55             a[i][n] -= (LL(a[i][j]) * a[j][n]) % MOD;
     56             if(a[i][n] < 0) a[i][n] += MOD;
     57         }
     58         a[i][n] = LL(a[i][n]) * inv(a[i][i]) % MOD;
     59     }
     60 }
     61 
     62 int la[MAXE], lb[MAXE], kind[MAXE];
     63 int T, n, m, k;
     64 
     65 int get_column(int a) {
     66     Mat mat(n, vector<int>(n));
     67     for(int i = 0; i < m; ++i) {
     68         int t = (kind[i] & 1) * a + (kind[i] >> 1);
     69         mat[la[i]][la[i]] += t;
     70         mat[lb[i]][lb[i]] += t;
     71         mat[la[i]][lb[i]] = mat[lb[i]][la[i]] = (t > 0 ? MOD - t : 0);
     72     }
     73     return det(mat, n);
     74 }
     75 
     76 int solve() {
     77     Mat mat(n, vector<int>(n + 1));
     78     for(int i = 0; i < n; ++i) {
     79         LL tmp = 1;
     80         for(int j = 0; j < n; ++j)
     81             mat[i][j] = tmp, tmp = (tmp * i) % MOD;
     82         mat[i][n] = get_column(i);
     83     }
     84     //debug(mat);
     85     guass(mat, n);
     86 
     87     int res = 0;
     88     for(int i = 0; i <= k; ++i) {
     89         res += mat[i][n];
     90         if(res >= MOD) res -= MOD;
     91     }
     92     return res;
     93 }
     94 
     95 int main() {
     96     scanf("%d", &T);
     97     for(int t = 1; t <= T; ++t) {
     98         scanf("%d%d%d", &n, &m, &k);
     99         for(int i = 0; i < m; ++i) {
    100             scanf("%d%d%d", &la[i], &lb[i], &kind[i]);
    101             la[i]--, lb[i]--;
    102         }
    103         printf("Case #%d: %d
    ", t, solve());
    104     }
    105 }
    View Code
  • 相关阅读:
    poj 2584 T-Shirt Gumbo (二分匹配)
    hdu 1757 A Simple Math Problem (乘法矩阵)
    矩阵之矩阵乘法(转载)
    poj 2239 Selecting Courses (二分匹配)
    hdu 3661 Assignments (贪心)
    hdu 1348 Wall (凸包)
    poj 2060 Taxi Cab Scheme (二分匹配)
    hdu 2202 最大三角形 (凸包)
    hdu 1577 WisKey的眼神 (数学几何)
    poj 1719 Shooting Contest (二分匹配)
  • 原文地址:https://www.cnblogs.com/oyking/p/4598601.html
Copyright © 2011-2022 走看看