zoukankan      html  css  js  c++  java
  • 【BZOJ】1016: [JSOI2008]最小生成树计数

    【题意】给定无向带权图,求最小生成树数。n<=100,m<=1000,相同权值边数<=10。

    【算法】最小生成树(MST),DFS

    【题解】首先需要一个结论:同个图的不同MST一定满足同个权值的边数相同

    考虑kruskal算法的过程,已经统计了<x的所有边,现在考虑=x的边,根据生成树的性质一定要尽量选择能连通两个集合的边,所以同个权值的边一定是选择边数相同且必须对集合连通的影响相同。

    先做一次MST得到每个权值的边数,然后dfs每个权值的选边情况得到总方案数。

    dfs中每次只能选择当前能连通两个集合的边,回溯的话就在find的时候不进行路径压缩即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1010,MOD=31011;
    struct edge{int u,v,w;}e[maxn];
    int be[maxn],ed[maxn],fa[maxn],num[maxn],n,m,tot;
    bool cmp(edge a,edge b){return a.w<b.w;}
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int found(int x){return fa[x]==x?x:found(fa[x]);}
    int dfs(int x,int p,int now){
        if(now==ed[x]+1)return p==num[x];
        int u=found(e[now].u),v=found(e[now].v),as=0;
        if(u!=v){
            fa[u]=v;
            as=dfs(x,p+1,now+1);
            fa[u]=u;
        }
        if(ed[x]-now+p>=num[x])as+=dfs(x,p,now+1);//jz
        return as;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=n;i++)fa[i]=i;
        int cnt=0;
        for(int i=1;i<=m;i++){
            if(e[i].w!=e[i-1].w)be[++tot]=i;
            if(e[i].w!=e[i+1].w)ed[tot]=i;
            if(find(e[i].u)!=find(e[i].v)){
                fa[fa[e[i].u]]=fa[e[i].v];
                num[tot]++;cnt++;
            }
        }
        if(cnt<n-1){printf("0");return 0;}
        for(int i=1;i<=n;i++)fa[i]=i;
        long long ans=1;
        for(int i=1;i<=tot;i++){
            ans=1ll*ans*dfs(i,0,be[i])%MOD;
            for(int j=be[i];j<=ed[i];j++)if(find(e[j].u)!=find(e[j].v)){
                fa[fa[e[j].u]]=fa[e[j].v];
            }
        }
        printf("%lld",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Linux上查找
    Linux进程
    Linux重定向
    Linux上常用的基本命令
    LInux上返回到切换目录前的目录
    【网络知识之一】4/7层网络模型
    【操作系统之十五】iptables黑白名单、自定义链、网络防火墙、常用动作
    【操作系统之十四】iptables扩展模块
    【操作系统之十三】Netfilter与iptables
    【操作系统之十二】分支预测、CPU亲和性(affinity)
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8142863.html
Copyright © 2011-2022 走看看