Consider the big plus edge from small to large, and then calculate the number of spanning trees for all the unicom blocks.
Then shrink them to a point and continue adding the next set.
The last multiplication principle can be.
It's disgusting, you write.
#include <queue> #include <cmath> #include <vector> #include <cstdio> #include <cstring># Include <iostream> #include <algorithm>using namespace std; #define F (I,J,K) for (int. i=j;i<=k;++i) #define D (I,J,K) for (int i=j;i>=k;--i) #define MAXN 1005#define EPS 1e-6const int md=31011;vector <int> v,to[maxn];queue <int> q;struct edge{int u,v,w;} A[maxn];int n,m,fa[maxn];int b[maxn][maxn],inv[maxn];int vcnt,du[maxn],list[maxn],vis[maxn];bool cmp (Edge X,Edge y) { return X.W<Y.W;} int GF (int k) {if (fa[k]==k) return k; else return FA[K]=GF (Fa[k]);} int gauss (int n) {f (i,1,n) F (j,1,n) b[i][j]%=md; int ret=1; for (int i=1;i<n;++i) {to (int j=i+1;j<n;++j) while (B[j][i]) {int T=b[i][i]/b[j][i]; for (int k=i;k<n;++k) b[i][k]= (B[I][K]-B[J][K]*T+MD)%md; for (int k=i;k<n;++k) swap (b[i][k],b[j][k]); REt=-ret; } if (b[i][i]==0) return 0; RET=RET*B[I][I]%MD; } return ABS ((RET+MD)%MD);} int main () {scanf ("%d%d", &n,&m); F (i,1,n) fa[i]=i; F (i,1,m) {scanf ("%d%d%d", &A[I].U,&A[I].V,&A[I].W);} Sort (a+1,a+m+1,cmp); int Now=1,ans=1; while (now<=m) {int l=now,r=now; vcnt=0; memset (du,0,sizeof du); F (I,1,n) to[i].clear (); while (A[R+1].W==A[R].W) r++; now=r+1; F (i,l,r) {int FL=GF (A[I].U), FR=GF (A[I].V); To[fl].push_back (FR); To[fr].push_back (FL); if (FL!=FR) du[fl]++,du[fr]++; } memset (vis,0,sizeof vis); F (I,1,n) if (Du[i]&&!vis[i]) {v.clear (); memset (b,0,sizeof b); memset (inv,0,sizeof inv); Q.push (i); inv[i]=1;vis[i]=1; while (!q.empty ()) {int X=q.front (); V.push_baCK (x); Q.pop (); for (int j=0;j<to[x].size (); ++j) if (!vis[to[x][j]]) Q.push (To[x][j]) , Inv[to[x][j]]=1,vis[to[x][j]]=1; } for (int j=0;j<v.size (); ++j) list[v[j]]=j+1; for (int j=0;j<v.size (), ++j) for (int k=0;k<to[v[j]].size (); ++k) if (inv[t O[v[j]][k]]) {b[list[v[j]]][list[v[j]]]++,b[list[v[j]]][list[to[v[j]][k ]]]--; } Ans*=gauss (V.size ()); ANS%=MD; } F (i,l,r) {int FL=GF (A[I].U), FR=GF (A[I].V); if (FL!=FR) {fa[fl]=fr;} }} int cnt=0; F (I,1,n) if (fa[i]==i) {cnt++; if (cnt==2) {printf ("0\n"); return 0;} } printf ("%d\n", ans);}
Bzoj 1016 [JSOI2008] minimum spanning tree count--matrix-tree theorem