@(XSY)[行列式, Matrix-Tree定理]
之前写过一个辗转相除版本的, 这里来一个求逆元的.
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
const int N = 80, MOD = (int)1e9 + 7;
int n, m;
int det[N + 1][N + 1];
namespace Zeonfai
{
inline int getInt()
{
int sgn = 1, a = 0;
char c;
while(! isdigit(c = getchar()))
if(c == '-')
sgn *= -1;
while(isdigit(c))
a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
}
inline int modPower(int a, int x)
{
int res = 1;
for(; x; a = (long long)a * a % MOD, x >>= 1)
if(x & 1)
res = (long long)res * a % MOD;
return res;
}
inline int gause()
{
for(int i = 1; i < n; ++ i)
for(int j = 1; j < n; ++ j)
det[i][j] = (det[i][j] + MOD) % MOD;
int sgn = 1;
for(int i = 1; i < n; ++ i)
{
int p = i;
for(; p < n; ++ p)
if(det[p][i])
break;
if(p >= n)
continue;
if(p ^ i)
{
sgn *= -1;
for(int j = 1; j < n; ++ j)
std::swap(det[i][j], det[p][j]);
}
int inv = modPower(det[i][i], MOD - 2);
for(int j = i + 1; j < n; ++ j)
if(det[i][j])
{
int tmp = (long long)det[j][i] * inv % MOD;
for(int k = i; k < n; ++ k)
det[j][k] = (det[j][k] - (long long)det[i][k] * tmp % MOD + MOD) % MOD;
}
}
int ans = 1;
for(int i = 1; i < n; ++ i)
ans = (long long)ans * det[i][i] % MOD;
if(sgn == -1)
ans = (MOD - ans) % MOD;
return ans;
}
/*
inline int gause()
{
for(int i = 1; i < n; i ++)
for(int j = 1; j < n; j ++)
det[i][j] = (det[i][j] + MOD) % MOD;
long long sgn = 0;
for(int i = 1; i < n; i ++)
{
int j;
for(j = i; j < n; j ++)
if(det[j][i])
break;
if(j == n)
continue;
if(i != j)
{
sgn ^= i ^ j;
for(int k = i; k < n; k ++)
std::swap(det[j][k], det[i][k]);
}
for(int j = i + 1; j < n; j ++)
while(det[j][i])
{
int tmp = det[j][i] / det[i][i];
for(int k = i; k < n; k ++)
det[j][k] = (det[j][k] - (long long)det[i][k] * tmp % MOD + MOD) % MOD;
if(! det[j][i])
break;
sgn ^= 1;
for(int k = i; k < n; k ++)
std::swap(det[i][k], det[j][k]);
}
}
long long ret = 1;
for(int i = 1; i < n; i ++)
ret = (ret * det[i][i]) % MOD;
if(sgn)
ret = (MOD - ret) % MOD;
return ret;
}*/
int main()
{
#ifndef ONLINE_JUDGE
freopen("treecount.in", "r", stdin);
freopen("treecount.out", "w", stdout);
#endif
using namespace Zeonfai;
n = getInt(), m = getInt();
memset(det, 0, sizeof(det));
for(int i = 0; i < m; ++ i)
{
int u = getInt(), v = getInt();
-- det[u][v], ++ det[u][u], -- det[v][u], ++ det[v][v];
}
printf("%d
", gause());
}