很显然的想法就是计算每条边的贡献,显然贡献就是边权
∗
*
∗选这条边的方案数,方案数为总生成树方案–去掉这条边的方案数,
暴力修改矩阵复杂度
O
(
m
n
3
)
O(mn^3)
O(mn3)
m
m
m 条边每次都只修改矩阵中一行的两个值,考虑优化计算去掉每条边的方案数。
假设
M
M
M 为代数余子矩阵,有
∣
A
∣
=
∑
i
=
1
n
A
i
,
j
∗
M
i
,
j
|A|=\sum_{i=1}^n A_{i,j}*M_{i,j}
∣A∣=i=1∑nAi,j∗Mi,j
每次就只修改
x
x
x 行中的两个位置,那我们把行列式按第
x
x
x 展开,预处理好代数余子矩阵后每次可以
O
(
1
)
O(1)
O(1) 计算行列式
复杂度
O
(
n
3
+
m
)
O(n^3+m)
O(n3+m)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define fr first
#define se second
#define mp make_pair
#define ll long long
int rd()
{
int sum = 0;char c = getchar();bool flag = true;
while(c < '0' || c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') sum = sum * 10 + c - 48,c = getchar();
if(flag) return sum;
else return -sum;
}
const int p = 1e9+7;
int n,m;
int cur,det;
int mat[310][310];
int f[310][310],g[310][310];
struct node{int l,r,v;}e[101000];
int mul(int a,int b){return 1ll*a*b%p;}
int calc(int a,int b){return (a+b)%p;}
int del(int a,int b){return ((a-b)%p+p)%p;}
int Pow(int a,int x){int now = 1;for(;x;x >>= 1,a = 1ll*a*a%p) if(x&1) now = 1ll*now*a%p;return now;}
void init(){
n = rd();m = rd();
rep(i,1,m) {
e[i].l = rd(),e[i].r = rd(),e[i].v = rd();
mat[e[i].l][e[i].l]++;
mat[e[i].l][e[i].r]--;
}
}
void get_det()
{
int cnt = 0;
rep(i,1,n-1){
rep(j,i,n-1) if(mat[j][i] != 0){
if(i != j) rep(k,1,n) swap(mat[i][k],mat[j][k]),cnt++;
break;
}
int tmp = Pow(mat[i][i],p-2);
rep(j,i+1,n){
int rate = mul(mat[j][i],tmp);
rep(k,i,n) mat[j][k] = del(mat[j][k],mul(rate,mat[i][k]));
}
}
det = cnt%2==0?1:-1;
rep(i,1,n-1) det = mul(det,mat[i][i]);
det = calc(det,0);
}
void solve()
{
int ans = 0,sigma = 0,cnt = 0;
rep(i,1,n){
rep(j,i,n) if(f[i][j] != 0){
if(i != j)
rep(k,1,n) swap(f[i][k],f[j][k]),swap(g[i][k],g[j][k]),cnt++;
break;
}
int tmp = Pow(f[i][i],p-2);
rep(j,1,n) if(j != i){
int rate = mul(tmp,f[j][i]);
sigma = calc(sigma,rate);
rep(k,1,n){
f[j][k] = del(f[j][k],mul(rate,f[i][k]));
g[j][k] = del(g[j][k],mul(rate,g[i][k]));
}
}
sigma = calc(sigma,mul(sigma,cnt));
rep(j,1,n) f[i][j] = mul(f[i][j],tmp),g[i][j] = mul(g[i][j],tmp);
}
rep(i,1,m){
int x = e[i].l,y = e[i].r,v = e[i].v;
ans = calc(ans,mul( det,mul( del(g[x][x],g[x][y]) , v ) ) );
}
printf("%d\n",ans);
}
int main(){
init();
rep(i,1,n) rep(j,1,n) f[i][j] = mat[j][i],g[i][j] = i==j;
get_det();
solve();
return 0;
}