One property is that several Benquan that make up the total edge weights of the smallest spanning tree are always equal
This means that the number of edges within a range of the same weights that are sorted by the right edge can be selected into the minimum spanning tree is fixed.
So just ask for a minimum spanning tree and record the number of WINS for each segment.
Then for each section of Dfs to find a legitimate solution, notice that DFS needs to be returned and set, so the non-path compression and check set
Then, according to the multiplication theorem, the results of each DFS are multiplied.
#include <iostream>#include <cstdio>#include <algorithm>using namespaceStdConst intn=1005, mod=31011;intn,m,ans=1, Sum,tot,cnt,l[n],r[n],c[n],f[n];structqwe{intU,v,w;} A[n];BOOLcmpConstQwe &a,ConstQwe &b) {returnA.W<B.W;}intZhaointx) {returnX==f[x]?x:zhao (F[x]);}voidDfsintQintWintK) {if(W==r[q]+1) {if(K==c[q]) sum++;return; }intFu=zhao (A[W].U), Fv=zhao (A[W].V);if(FU!=FV) {F[FU]=FV; DFS (q,w+1K+1); F[FU]=FU,F[FV]=FV; } DFS (q,w+1, k);}intMain () {scanf ("%d%d", &n,&m); for(intI=1; i<=m;i++) scanf ("%d%d%d", &A[I].U,&A[I].V,&A[I].W); Sort (A+1A+1+M,CMP); for(intI=1; i<=n;i++) f[i]=i; for(intI=1; i<=m;i++) {if(A[i].w!=a[i-1].W) r[cnt]=i-1, L[++cnt]=i;intFu=zhao (A[I].U), Fv=zhao (A[I].V);if(FU!=FV) TOT++,C[CNT]++,F[FU]=FV; }if(tot!=n-1) {puts ("0");return 0; } r[cnt]=m; for(intI=1; i<=n;i++) f[i]=i; for(intI=1; i<=cnt;i++) {sum=0; DFS (I,l[i),0); Ans=ans*sum%mod; for(intj=l[i];j<=r[i];j++) {intFu=zhao (A[J].U), Fv=zhao (A[J].V);if(FU!=FV) F[FU]=FV; }} printf ("%d\n", ans);return 0;}
Bzoj 1016: [JSOI2008] minimum spanning tree count "dfs+ Kruskal"