luogu4208

P4208 [JSOI2008] minimum spanning tree count

Title Description

Now gives a simple weighted undirected FIG. You are not satisfied with the minimum spanning tree calculated this figure, but would like to know how many different minimum spanning tree this figure there. (If there are at least two different sides of a minimum spanning tree, then both the minimum spanning tree is different). Since different minimum spanning tree may be a lot, so you only need to program the number of analog output 31011 on it.

Input Format

The first line contains two numbers, n and m, where 1 <= n <= 100; 1 <= m <= 1000; represents the number of nodes and edges in the undirected graph. Each node with an integer number of 1 ~ n.

The next m rows, each row comprising two integers: a, b, c, represents the node a, the right side between the b value c, where 1 <= c <= 1,000,000,000.

Data does not appear self-assurance back side and heavy side. Note: the same edge weight value is not more than 10.

Output Format

Different output minimum spanning tree how many. You only need to output the number of mold 31011 on it.

Sample input and output

Input # 1
4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
Output # 1
8

Description / Tips

说明 1<=n<=100; 1<=m<=1000;1<=ci<=1e9

 

sol: minimum spanning tree of the same weight have a very metaphysical feature is the number of the fixed side and the right side of the same effect is the same, then the same number of sides can burst search out program, as long as the attention point is found the program disjoint-set path can not be compressed when the number, otherwise hang back when back

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0; bool f=0; char ch=' ';
    while(!isdigit(ch))    {f|=(ch=='-'); ch=getchar();}
    while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0) {putchar('-'); x=-x;}
    if(x<10) {putchar(x+'0'); return;}
    write(x/10); putchar((x%10)+'0');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=105,M=1005,Mod=31011;
int n,m,fa[N],lian[N];
struct Edge
{
    int u,v,w;
}E[M];
inline bool cmpw(Edge p,Edge q) {return p.w<q.w;}
inline int gf(int x){return (fa[x]==x)?x:fa[x]=gf(fa[x]);}
inline int gl(int x){return (lian[x]==x)?x:gl(lian[x]);}
inline int dfs(int now,int end,int cnt)
{
    if(now==end+1)
    {
        if(cnt==0) return 1;
        return 0;
    }
    int ans=dfs(now+1,end,cnt);
    int fx=gl(E[now].u),fy=gl(E[now].v);
    if(fx!=fy)
    {
        lian[fx]=fy;
        ans+=dfs(now+1,end,cnt-1);
        lian[fx]=fx;
    }
    return ans;
}
int main()
{
    int i,j,tot=0;
    R(n); R(m);
    for(i=1;i<=m;i++)
    {
        R(E[i].u); R(E[i].v); R(E[i].w);
    }sort(E+1,E+m+1,cmpw);
    for(i=1;i<=n;i++) fa[i]=i;
    int ans=1;
    for(i=1;i<=m;)
    {
        for(j=1;j<=n;j++) lian[j]=j;
        int oo=i,now=tot;
        while(i<=m&&E[i].w==E[oo].w)
        {
            E[i].u=gf(E[i].u); E[i].v=gf(E[i].v); i++;
        }
        for(j=oo;j<i;j++)
        {
            int fx=gf(E[j].u),fy=gf(E[j].v);
            if(fx!=fy)
            {
                tot++; fa[fx]=fy;
            }
        }
        ans=1LL*ans*dfs(oo,i-1,tot-now)%Mod;
    }
    if(tot==n-1) Wl(ans);
    else puts("0");
    return 0;
}
View Code

 

 

Guess you like

Origin www.cnblogs.com/gaojunonly1/p/11329536.html