zoukankan      html  css  js  c++  java
  • 最小生成树计数(有一个神奇的操作)

    有一个定理:无论最小生成树由哪些边组成,其中使用的每种边权的边的数量是一定的

    所以由此我们可以得到一种做法:记录最小生成树使用的每种边的数量,然后dfs使用这些边去构建另一棵最小生成树

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=31011;
    int n,m,sum;
    struct node{
        int x,y,w;
    }e[9999999];
    struct Node{
        int l,r,len;
    }a[9999999];
    int pre[9999999];
    bool cmp(node a,node b){
        return a.w<b.w;
    }
    void read(int &x)
    {
        int f=1;x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        x*=f;
    }
    void print(int x)
    {
        if(x<0){putchar('-');x=-x;}
        if(x>9){print(x/10);}
        putchar(x%10+'0');
    }
    int find(int x)
    {
        //return x==pre[x]?x:pre[x]=find(pre[x]); //写成x:pre[x]=find(pre[x]);不对 
        return x==pre[x]?x:find(pre[x]);
        //此题不该路径压缩 
    } 
    void dfs(int x,int now,int k)
    {
        if(now==a[x].r+1)
        {
            if(k==a[x].len){
                ++sum;
            }
            return;
        }
        int p=find(e[now].x),q=find(e[now].y);
        if(p!=q){
            pre[p]=q;
            dfs(x,now+1,k+1);
            pre[p]=p;pre[q]=q;
        }
        dfs(x,now+1,k);
    }
    int main()
    {
        read(n),read(m);
        for(register int i=1;i<=n;++i) pre[i]=i;
        int tot=0,cnt=0,ans=1;    
        for(register int i=1;i<=m;i++)
            read(e[i].x),read(e[i].y),read(e[i].w);
        sort(e+1,e+m+1,cmp);
        for(register int i=1;i<=m;++i)
        {
            if(e[i].w!=e[i-1].w)
            {
                a[++cnt].l=i;
                a[cnt-1].r=i-1;
            }
            int p=find(e[i].x);
            int q=find(e[i].y);
            if(p!=q)
            {
                pre[p]=q;
                a[cnt].len++;
                tot++;
            }
        }
        a[cnt].r=m;
        if(tot!=n-1){
            putchar('0');return 0;
        }
        for(register int i=1;i<=n;i++) pre[i]=i;
        for(register int i=1;i<=cnt;++i)
        {
            sum=0;
            dfs(i,a[i].l,0);
            ans=(ans*sum)%mod;
            for(register int j=a[i].l;j<=a[i].r;++j)
            {
                int p=find(e[j].x),q=find(e[j].y);
                if(p!=q){
                    pre[p]=q;
                }
            }
        }
        print(ans);
        return 0;
    }
  • 相关阅读:
    重构FourlegLayers控件
    XNA 没有经过Content Pipeline对内容做Alpha预处理解决办法
    山寨DNF
    XNA中 SpriteSortMode 与 BlendState 《摘自王磊文章》
    HDU1060 Leftmost Digit
    HDU1095 A hard puzzle
    magento安装心得
    关于小米手机网站抢购的一点技术分析
    MVC3和MVC4内置Razor引擎的差异
    查看进程
  • 原文地址:https://www.cnblogs.com/719666a/p/9537944.html
Copyright © 2011-2022 走看看