zoukankan      html  css  js  c++  java
  • bzoj1016: [JSOI2008]最小生成树计数

    最小生成树+dfs。

    首先可知某一特定权值的边的数量在不同的最小生成树是确定的。(可以用反证法yy一下)

    这样先用kruskal算法求最小生成树,一边统计某种边用的数量。

    然后dfs一下(就是枚举每条边有没有,因为相同权值的边最多只有10条,所以是O(2^n)的枚举可以胜任)。

    同时要注意图是否联通,不联通输出0.

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 100 + 10;
    const int maxm = 2000 + 10;
    const int mod = 31011;
    
    struct Edge {
        int u,v,w;
    } e[maxm];
    
    int n,m,p,cnt,tot,cur,res=1;
    
    struct S {
        int f[maxn];
        
        int find(int x) {
            return f[x]==x?x:f[x]=find(f[x]);
        }
        
        bool merge(int u,int v) {
            int ru=find(u),rv=find(v);
            if(ru != rv) {
                f[ru]=rv;
                return true;    
            }
            return false;
        }
        
        void init(int n) {
            for(int i=1;i<=n;i++) f[i]=i;
        }
    } s1,s2;
    
    bool cmp(Edge a,Edge b) {
        return a.w < b.w;    
    }
    
    void dfs(int l,int r,int cnt,int &cur) {
        if(l>r) {
            if(cnt==0) cur++;
            return;
        }
        S tmp = s2;
        if(s2.merge(e[l].u,e[l].v)) dfs(l+1,r,cnt-1,cur);
        s2=tmp;
        dfs(l+1,r,cnt,cur);
    }
    
    void build() {
        scanf("%d%d",&n,&m);
        s1.init(n); s2.init(n);
        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);
        
        tot=n,p=1;
        for(int i=1;i<=m+1;i++) {
            if(e[i].w != e[i-1].w) {
                dfs(p,i-1,cnt,cur=0);
                res=res*cur%mod;
                p=i; cnt=0; s2=s1;    
            }
            if(s1.merge(e[i].u,e[i].v)) {
                cnt++; tot--;    
            }
        }
        
        if(tot==1) printf("%d
    ",res);
        else printf("0
    ");
    }
    
    int main() {
        build();
        return 0;    
    }
  • 相关阅读:
    PAT (Basic Level) Practice (中文)1076 Wifi密码 (15 分)
    PAT (Basic Level) Practice (中文)1047 编程团体赛 (20 分)
    PAT (Basic Level) Practice (中文)1029 旧键盘 (20 分)
    PAT (Basic Level) Practice (中文)1016 部分A+B (15 分)
    延迟加载
    Js之全局函数
    Js之数组
    前端性能优化
    排序算法小结
    CSS居中总结
  • 原文地址:https://www.cnblogs.com/invoid/p/5512697.html
Copyright © 2011-2022 走看看