Problem Descriptionxxx is very interested in algorithm. After learning the Prim algorithm and Kruskal algorithm of minimum spanning tree, XXX finds this there might be multiple s Olutions. Given an undirected weighted graph with n (1<=n<=100) vertexes and M (0<=m<=1000) edges, he wants to know the Number of minimum spanning trees in the graph.
Inputthere is no more than cases. The input ends by 0 0 0.
For each case, the first line begins with three integers---the above mentioned N, M, and P. The meaning of P would be explained later. Each of the following m lines contains three integers u, V, W (1<=w<=10), which describes that there was an edge Weighte D W between vertex u and Vertex v (all vertex is numbered for 1 to N). It is guaranteed This there is no multiple edges and no loops in the graph.
Outputfor each test case, output a single integer on one line representing the number of different minimum spanning trees In the graph.
The answer may quite large. You just need to calculate the remainder of the answer when divided by P (1<=p<=1000000000). P is above mentioned, appears in the first line of each test case.
Sample INPUT5 10 122 5 32 4 23 1 33 4 21 2 35 4 35 1 34 1 15 3 33 2 30 0 0
Sample Output4
Source2012 ACM/ICPC Asia Regional Jinhua Online
Recommendzhoujiaqi2010 | We have carefully selected several similar problems for you:5831 5830 5829 5828 5827
Test instructions is a given n-point, M-edge of the graph, to find the minimum number of spanning tree p modulo.
When the minimum spanning tree is calculated with kruscal, the smallest edge of two different unicom blocks is taken each time. That is, the edge of the c1 length of the D1 bar is processed first, and the edge of the D2 C2 length is processed. Regardless of the length of the same side of the choice, the maximum connectivity situation is fixed. The number of connected blocks generated by the CI-length edges is multiplied, then the ci+1 is shrunk and the edge of the length is computed.
Spanning tree count with the Matrix-tree theorem, the previous article is no heavy edge, the problem of the indentation is to produce a heavy edge, Matrix-tree is also applicable:
The absolute value of the determinant of any n-1 order matrix of the Kirchhoff matrix is the number of spanning trees of the non-graph.
The definition of the Kirchhoff matrix is the degree matrix-adjacency matrix.
1, G of the degree matrix D[g]:n*n Matrix, DII equals the degree of VI, the remaining 0.
2, G of the adjacency matrix A[g]:n*n Matrix, Vi, VJ between the edge is directly connected, then Aij=ij between the number of sides, otherwise 0.
And check set Fa[i] is the current length, the node belongs to the Unicom block, Ka[i] is the current length of the edge connected after it in the Unicom block.
#include <cstdio> #include <cstring> #include <algorithm> #include <vector>using namespace std; typedef long Long ll;const int n=101; const int M=1001;LL n,m,p,ans;vector<int>gra[n];struct edge{int u,v,w;} E[m];int cmp (Edge A,edge b) {return A.W<B.W;} ll Mat[n][n],g[n][n];ll fa[n],ka[n],vis[n];ll det (ll c[][n],ll N) {ll i,j,k,t,ret=1;for (i=0;i<n;i++) for (j=0;j<n ; j + +) c[i][j]%=p;for (i=0; i<n; i++) {for (j=i+1; j<n; J + +) while (C[j][i]) {t=c[i][i]/c[j][i];for (k=i; k<n; k++) C I [K]= (C[i][k]-c[j][k]*t)%p;swap (C[i],c[j]); ret=-ret;} if (c[i][i]==0) return 0l;ret=ret*c[i][i]%p;} Return (RET+P)%p;} ll find (ll A,ll f[]) {return f[a]==a?a:find (f[a],f);} void Matrix_tree () {//per Unicom block for the edge connection of the current length calculation spanning tree number for (int i=0;i<n;i++) if (Vis[i]) {///current-length edge connected I-node gra[find (I,ka)].push_ Back (i);//press the I node into the connected Unicom block vis[i]=0;//side to empty the VIS array}for (int i=0;i<n;i++) if (Gra[i].size () >1) {// The number of points for the Unicom block is 1 o'clock the spanning tree is 1memset (mat,0,sizeof mat);//empties The matrix int len=gra[i].size (); for (int j=0;j<len;j++) for (int k=j+1;k< Len;k+ +) {//construct this unicom block's matrix (with heavy edges) int u=gra[i][j],v=gra[i][k];if (G[u][v]) {mat[k][j]= (mat[j][k]-=g[u][v]); mat[k][k]+=g[u][v]; MAT[J][J]+=G[U][V];}} Ans=ans*det (Mat,gra[i].size ()-1)%p;for (int j=0;j<len;j++) fa[gra[i][j]]=i;//indent}for (int i=0;i<n;i++) {gra[i]. Clear (); Ka[i]=fa[i]=find (I,FA);}} int main () {while (scanf ("%lld%lld%lld", &n,&m,&p), N) {for (int i=0;i<m;i++) {int u,v,w;scanf ("%d%d%d", &U,&V,&W); u--;v--;e[i]= (Edge) {u,v,w};} Sort (e,e+m,cmp); memset (g,0,sizeof g); Ans=1;for (ll i=0;i<n;i++) ka[i]=fa[i]=i;for (ll i=0;i<=m;i++) {// Edge from small to large join if (i&&e[i].w!=e[i-1].w| | I==M)//processing all sides of the length of E[I-1].W matrix_tree ();//compute Spanning Tree ll u=find (E[I].U,FA), V=find (E[I].V,FA),//two points after the point if (u!=v)// If not a {Vis[v]=vis[u]=1;ka[find (U,ka)]=find (V,ka);//Two components in a unicom block. g[u][v]++,g[v][u]++;//adjacency matrix}}int flag=1;for (int i=1;i<n;i++) if (Fa[i]!=fa[i-1]) flag=0;printf ("%lld\n", flag?ans% p:0)///Note p may be 1, so m=0 if ans does not%p will output 1}}
"HDU 4408" Minimum Spanning tree (minimum spanning trees count)