• [HEOI2015]小Z的房间 && [CQOI2018]社交网络


    今天看了一下矩阵树定理,然后学了一下(O(n ^ 3))的方法求行列式。
    哦对了,所有的证明我都没看……


    这位大佬讲的好呀:
    [学习笔记]高斯消元、行列式、Matrix-Tree 矩阵树定理


    关于模数不是质数的情况,我看了半天才懂:其实就是加速了两行的辗转相减,把一次次减换成了取模。然后别忘了每一次交换两行的时候行列式要取相反数。


    [HEOI2015]小Z的房间
    这题就是板儿题了。把是'.'的格子记录下来,然后构造基尔霍夫矩阵就行了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 105;
    const ll mod = 1e9;
    inline ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    inline void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    
    int n, m, cnt = 0, id[maxn][maxn];
    char s[maxn][maxn];
    ll f[maxn][maxn];
    
    In void add(int x, int y)
    {
      ++f[x][x], ++f[y][y], --f[x][y], --f[y][x];
    }
    
    In ll Gauss(int n)
    {
      ll ans = 1;
      for(int i = 1; i <= n; ++i)
        {
          for(int j = i + 1; j <= n; ++j)
    	while(f[j][i])
    	  {
    	    ll d = f[i][i] / f[j][i];
    	    for(int k = i; k <= n; ++k) f[i][k] = (f[i][k] - d * f[j][k] % mod + mod) % mod;
    	    swap(f[i], f[j]), ans = -ans;
    	  }
          ans = (ans * f[i][i] % mod + mod) % mod;
        }
      return ans;
    }
    
    int main()
    {
      n = read(), m = read();
      for(int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);
      for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j) if(s[i][j] == '.') id[i][j] = ++cnt;
      for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
          if(id[i][j])
    	{
    	  if(id[i][j + 1]) add(id[i][j], id[i][j + 1]);
    	  if(id[i + 1][j]) add(id[i][j], id[i + 1][j]);
    	}
      write(Gauss(cnt - 1)), enter;
      return 0;
    }
    

    [[CQOI2018]社交网络](https://www.luogu.org/problemnew/show/P4455) 这题让求的是以节点1为根的生成树个数,于是我们把矩阵的第一行第一列消去,剩下的求一个行列式就是答案了。 注意连边是反的。 ```c++ #include #include #include #include #include #include #include #include #include #include using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 255; const ll mod = 1e4 + 7; inline ll read() { ll ans = 0; char ch = getchar(), last = ' '; while(!isdigit(ch)) last = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); if(last == '-') ans = -ans; return ans; } inline void write(ll x) { if(x < 0) x = -x, putchar('-'); if(x >= 10) write(x / 10); putchar(x % 10 + '0'); }

    int n, m;
    ll f[maxn][maxn];

    In ll quickpow(ll a, ll b)
    {
    ll ret = 1;
    for(; b; b >>= 1, a = a * a % mod)
    if(b & 1) ret = ret * a % mod;
    return ret;
    }

    In ll Gauss()
    {
    ll ans = 1;
    for(int i = 2; i <= n; ++i)
    {
    int pos = i;
    while(!f[pos][i]) ++pos;
    if(pos ^ i) swap(f[i], f[pos]), ans = mod - ans;
    if(!f[i][i]) return 0; //如果每一行第i个数都输0,才返回0
    ans = ans * f[i][i] % mod;
    ll inv = quickpow(f[i][i], mod - 2);
    for(int j = i + 1; j <= n; ++j)
    {
    ll tp = f[j][i] * inv % mod;
    for(int k = i; k <= n; ++k) f[j][k] = (f[j][k] - tp * f[i][k] % mod + mod) % mod;
    }
    }
    return ans;
    }

    int main()
    {
    n = read(), m = read();
    for(int i = 1; i <= m; ++i)
    {
    int y = read(), x = read(); //x -> y
    ++f[y][y], --f[y][x];
    }
    write(Gauss()), enter;
    return 0;
    }

  • 相关阅读:
    4.19Java.util.Arrays类
    4.19Java数组的拷贝
    Inverse matrix of 4x4 matrix
    自言自语
    病了两天
    当年3ds max盗版光碟上的广告
    头晕的厉害
    复习了一下STL容器的知识
    一个简单的能处理MIPMAP的类
    空间变换代码,相当简洁优美
  • 原文地址:https://www.cnblogs.com/mrclr/p/10465598.html
Copyright © 2020-2023  润新知