1016: [JSOI2008] minimum spanning tree count
Title: Portal
Exercises
God problem%%%
It is said that the minimum spanning tree has two magic theorems:
1, the equal weight of the edge in the number of different schemes equal number of sides
That is, if an edge with a weight of 1 in a scheme has n bars
Then there must be N in another scenario where the weight is 1.
2, if the edge of the edge of 1 is connected to the point is x1,x2,x3
It must be x1,x2,x3 that the side of the Edge 1 is connected in another scheme.
   
If you know the two theorems, then it's good to do it:
Because the number of bars of equal weights is certain, then we can preprocess to find the number of edges of different edge weights.
The subject is very humane to ensure that Benquan the same side will not more than 10, then you can be fair and square recursion to get the number of programs AH
The next step is to use Theorem 2:
Because the point of the connection is always constant, so every time the selection is not affected, then recursive to find out the number of each weighted edge of the scheme after the multiplication principle to multiply it OK
Code:
1#include <cstdio>2#include <cstring>3#include <cstdlib>4#include <cmath>5#include <algorithm>6 #defineMoD 310117 #defineQread (x) X=read ()8 using namespacestd;9InlineintRead ()Ten { One     intf=1, x=0;Charch; A      while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();} -      while(ch>='0'&& ch<='9') {x=x*Ten+ch-'0'; ch=GetChar ();} -     returnf*x; the } - structnode - { -     intX,y,c,next; +}a[1100];intn,m,sum; - inteax the]; + intFINDFA (intx) A { at     if(X==fa[x])returnx; -     returnFindfa (fa[x]); - } - BOOLCMP (node n1,node n2) - { -     returnn1.c<n2.c; in } - intd[1100],s[1100]; to voidDfsintKintTintI//The current selection is the K-type side, has selected the T bar, the current position is the first edge + { -     if(i==s[k]+1) the     {  *         if(t==D[k]) $sum++,sum%=MoD;Panax Notoginseng         return ; -     } the     intFX=FINDFA (a[i].x), fy=Findfa (A[I].Y); +     if(fx!=fy) A     { thefa[fx]=fy; +DFS (k,t+1, i+1); -fa[fx]=FX; $     } $DFS (k,t,i+1); - } - intMain () the { - qread (n); Qread (m);Wuyi      for(intI=1; i<=m;i++{qread (a[i].x); Qread (A[I].Y); Qread (A[I].C);} theSort (A +1, a+m+1, CMP); -      for(intI=1; i<=n;i++) fa[i]=i; Wu     intk=1, t=0; Memset (d,0,sizeof(d)); memset (s),0,sizeof(s)); -      for(intI=1; i<=m;i++) About     { $         intFX=FINDFA (a[i].x), fy=Findfa (A[I].Y); -         if(a[i].c!=a[i-1].C) s[k]=i-1, k++;//record the last position of the K-type edge -         if(fx!=fy) -         { Afa[fx]=fy; +t++;d [k]++; the         } -     } $s[k]=m; the     if(t!=n-1) {printf ("0\n");return 0;} the      for(intI=1; i<=n;i++) fa[i]=i; the     intans=1; the      for(intI=1; i<=k;i++) -     { insum=0; theDFS (I,0, s[i-1]+1); theans= (ans*sum)%MoD; About          for(intj=s[i-1]+1; j<=s[i];j++) the         { the             intFX=FINDFA (a[j].x), fy=Findfa (A[J].Y); the             if(fx!=fy) fa[fx]=fy; +         } -     } theprintf"%d\n", ans);Bayi     return 0; the}
 bzoj1016: [JSOI2008] minimum spanning tree count (Kruskal+dfs)