• 最小生成树计数(有一个神奇的操作)


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

    所以由此我们可以得到一种做法:记录最小生成树使用的每种边的数量,然后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;
    }
  • 相关阅读:
    搭建自己的技术博客系列(三)让你的博客拥有评论功能!
    搭建自己的技术博客系列(二)把 Hexo 博客部署到 GitHub 上
    Excel2003 去除重复项
    Delphi 7拦截滚轮事件不响应滚轮的上下滚动
    APSC4xSeries_Ver32.exe在win764位提示缺少DLL错误解决办法
    Win7装在其他盘 (非C盘)办法
    Delphi7 安装ICS,与简单使用
    Python学习笔记
    使用IP spoofer 功能
    python在windows里怎么配置apache呢,
  • 原文地址:https://www.cnblogs.com/719666a/p/9537944.html
Copyright © 2020-2023  润新知