bzoj 5297 [Cqoi2018]社交网络 高斯消元+Matrix-Tree定理
题面
解法
有向图Matrix-Tree定理的裸题吧……
若\((i,j)\)有边,那么\(a_{i,j}=-1\),\(a_{i,i}=d_i\),\(d_i\)为点\(i\)的出度
因为以1为根,所以只要求出\(2-n\)的行列式即可
md高斯消元写错一个东西照样90……数据是真的弱
时间复杂度:\(O(n^3)\)
代码
#include <bits/stdc++.h>
#define Mod 10007
#define N 300
using namespace std;
template <typename node> void read(node &x) {
x = 0; int f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
int a[N][N];
int Pow(int x, int y) {
int ret = 1;
while (y) {
if (y & 1) ret = 1ll * ret * x % Mod;
y >>= 1, x = 1ll * x * x % Mod;
}
return ret;
}
int solve(int n) {
int ans = 1;
for (int i = 2; i <= n; i++) {
if (!a[i][i])
for (int j = i + 1; j <= n; j++)
if (a[j][i]) {
for (int k = 2; k <= n; k++) swap(a[j][k], a[i][k]);
ans = -ans; break;
}
int x = Pow(a[i][i], Mod - 2);
for (int j = i + 1; j <= n; j++)
if (a[j][i]) {
int t = 1ll * a[j][i] * x % Mod;
for (int k = 2; k <= n; k++) a[j][k] = (a[j][k] - t * a[i][k] % Mod + Mod) % Mod;
}
}
for (int i = 2; i <= n; i++) ans = (ans * a[i][i]) % Mod;
return (ans + Mod) % Mod;
}
int main() {
int n, m; read(n), read(m);
for (int i = 1; i <= m; i++) {
int x, y; read(x), read(y);
a[x][y] = (a[x][y] - 1 + Mod) % Mod, a[x][x]++;
}
cout << solve(n) << "\n";
return 0;
}