如题。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=210,maxm=2010,mod=31011;
int n,m;
struct edge{
int s,e,v;
}e[maxm];
bool operator < (edge a,edge b){
return a.v<b.v;
}
void init(){
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>e[i].s>>e[i].e>>e[i].v;
}
int fa[maxn];
void csh(){
for(int i=0;i<maxn;i++)fa[i]=i;
}
int find(int x){
while(x!=fa[x])x=fa[x];
return x;
}
void add(int a,int b){
fa[find(a)]=find(b);
}
int lefts[maxn],rights[maxn],num;
void makeit(){
int last=-1;
sort(e+1,e+m+1);
for(int i=1;i<=m;i++){
if(last!=e[i].v){
rights[num]=i-1;
lefts[++num]=i;
last=e[i].v;
}
}
rights[num]=m;
}
int cnt[maxn];
bool Kruskal(){
int tot=0;csh();
for(int i=1;i<=m;i++){
if(find(e[i].s)!=find(e[i].e)){
tot++;
add(e[i].s,e[i].e);
cnt[upper_bound(lefts+1,lefts+num+1,i)-lefts-1]++;
if(tot==n-1)break;
}
}
return tot==n-1;
}
int dfsans;
void dfs(int i,int x,int choose){
if(i==rights[x]+1){
if(choose==cnt[x]){
dfsans++;
dfsans%=mod;
}
return;
}
if(rights[x]-i+1>cnt[x]-choose)dfs(i+1,x,choose);
if(choose<cnt[x]){
int p=find(e[i].s),q=find(e[i].e);
if(p!=q){
fa[p]=q;dfs(i+1,x,choose+1);
fa[p]=p;
}
}
}
void BA(int x){
for(int i=lefts[x];i<=rights[x];i++)add(e[i].s,e[i].e);
}
signed main(){
init();makeit();
if(!Kruskal()){
cout<<0;return 0;
}
csh();int ans=1;
for(int i=1;i<=num;i++){
dfsans=0;
dfs(lefts[i],i,0);
ans*=dfsans;ans%=mod;
BA(i);
}
cout<<ans;return 0;
}