题解
题目的意思就求一个图的生成树个数,还有所有生成树的权值乘积和。
其实这题是一道非常简单的题目,只要知道矩阵树定理就好了。
code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
#define N 303
#define P putchar
#define G getchar
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
const int mo=998244353;
int n,m,x,y,z,d[N];
int a[N][N],b[N][N];
ll ans;
ll ksm(ll x,int y)
{
ll s=1;
for(;y;y>>=1,x=x*x%mo)
if(y&1)s=s*x%mo;
return s;
}
ll calc()
{
for(int i=1;i<n;i++)
for(int j=i+1;j<n;j++)
{
ll p=ksm(a[i][i],mo-2)*a[j][i]%mo;
for(int k=i;k<n;k++)
a[j][k]=(a[j][k]-p*a[i][k]%mo+mo)%mo;
}
ll s=1;
for(int i=1;i<n;i++)
s=s*a[i][i]%mo;
return s;
}
int main()
{
freopen("avg.in","r",stdin);
freopen("avg.out","w",stdout);
read(n);read(m);
for(int i=1;i<=m;i++)
{
read(x);read(y);read(z);
a[x][y]--;a[x][x]++;
a[y][x]--;a[y][y]++;
b[x][y]=(b[x][y]-z+mo)%mo;
b[x][x]=(b[x][x]+z)%mo;
b[y][x]=(b[y][x]-z+mo)%mo;
b[y][y]=(b[y][y]+z)%mo;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=(a[i][j]+mo)%mo;
ans=ksm(calc(),mo-2);
memcpy(a,b,sizeof(b));
ans=ans*calc()%mo;
printf("%lld",ans);
return 0;
}