The main idea of the topic: how many minimum spanning trees are there in a graph?
answer
The minimum spanning tree has a property, that is, the number of edges of each length is fixed.
So first find a minimum spanning tree, consider the length as iiFor the side of i , first change the length to notiiThe edges in the minimum spanning tree of i are added, and then a number of connected blocks are formed, and the remaining problem is to use a length ofiiObviously, the matrix tree theorem can be used to find how many schemes there are for the edges of i to connect these connected blocks into a tree.
Finally, multiplying the number of plans for each length is the answer.
code show as below:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 110
#define mod 31011
int n,m,ans=1;
struct edge{
int x,y,z;}e[1010];
int belong[maxn];bool v[1010];
struct BCJ{
int fa[maxn];
void init(){
for(int i=1;i<=n;i++)fa[i]=i;}
int findfa(int x){
return x==fa[x]?x:fa[x]=findfa(fa[x]);}
bool linked(int x,int y){
return findfa(x)==findfa(y);}
bool link(int x,int y)
{
x=findfa(x),y=findfa(y);
if(x==y)return false;
fa[y]=x;return true;
}
}F;
bool cmp(edge x,edge y){
return x.z<y.z;}
int dec(int x){
return x<0?x+mod:x;}
int f[maxn][maxn];int det(int l)
{
int re=1,fu=1;
for(int i=1,p;i<=l;i++)
{
for(int j=i+1;j<=l;j++)
while(f[j][i]!=0){
p=f[i][i]/f[j][i];
for(int k=i;k<=l;k++)f[i][k]=f[i][k]-f[j][k]*p;
swap(f[i],f[j]); fu=-fu;
}
re=1ll*re*f[i][i]%mod;
}
return re*fu;
}
int main()
{
scanf("%d %d",&n,&m);for(int i=1;i<=m;i++)
scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].z);sort(e+1,e+m+1,cmp);
F.init();for(int i=1;i<=m;i++)if(F.link(e[i].x,e[i].y))v[i]=true;
for(int i=2;i<=n;i++)if(F.findfa(i)!=F.findfa(1))return printf("0"),0;
int now=1;while(now<=m)
{
bool con=false;int to=now;for(;e[to].z==e[now].z&&to<=m;to++)con|=v[to];if(!con){
now=to;continue;}
F.init();for(int i=1;i<=m;i++)if(v[i]&&e[i].z!=e[now].z)F.link(e[i].x,e[i].y);
int id=0;memset(belong,0,sizeof(belong));memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)if(F.fa[i]==i)belong[i]=++id;
for(int i=1;i<=n;i++)belong[i]=belong[F.findfa(i)];
for(int i=now;i<to;i++){
int x=belong[e[i].x],y=belong[e[i].y];
f[x][y]--,f[y][x]--,f[x][x]++,f[y][y]++;
}
ans=1ll*ans*det(id-1)%mod;now=to;
}
printf("%d",ans);
}