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

    题目链接

    bzoj1016: [JSOI2008]最小生成树计数

    题解

    每种权值的边的数量是确定的,每种权值的边的作用是确定的
    求一遍最小生成树,对于相同权值的边分组
    然后对于每一种权值的边搜索,得出每组权值的边选择方案
    乘法原理统计答案

    代码

    #include<cstdio>
    #include<algorithm> 
     
    inline int read() { 
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} 
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
        return x * f;
    } 
    const int maxn = 1007; 
    struct Edge{int u,v,w; 
        bool operator < (const Edge &a)const { 
            return w < a.w;
        } 
    }edge[maxn]; 
    #define mod 31011
    struct Data {
        int l,r,v;
    }a[maxn]; 
    int fa[maxn],n,ans = 1,sum = 0,m; 
    int find(int x) { if(fa[x] != x) return find(fa[x]);else return x;  }
    void dfs(int x,int now,int k) {
        if(now == a[x].r + 1) {
            if(k == a[x].v) sum ++;
            return ;
        }
        int p = find(edge[now].u),q = find(edge[now].v); 
        if(p != q) {
            fa[p] = q; 
            dfs(x,now + 1,k + 1); 
            fa[p] = p;fa[q] = q; 
        }
        dfs(x,now + 1,k); 
    }   
    int main() {
        n = read(),m = read();  
        for(int i = 1;i <= m;++ i) {
            edge[i].u = read();
            edge[i].v = read();
            edge[i].w = read();fa[i] = i; 
        }
        int cnt = 0,tot = 0;
        std::sort(edge + 1,edge + m + 1); 
        for(int i = 1;i <= m;++ i) {
            if(edge[i].w != edge[i - 1].w) a[cnt].r = i - 1,a[++cnt].l = i;
            int p = find(edge[i].u),q = find(edge[i].v); 
            if(p != q) {fa[p] = q;a[cnt].v++;tot++; }
        } 
        a[cnt].r = m; 
        if(tot != n - 1)puts("0");
        else {
            for(int i = 1;i <= n;++ i) fa[i] = i; 
            for(int i = 1;i <= cnt;++ i) {
                sum = 0;  
                dfs(i,a[i].l,0); 
                ans = ans * sum % mod;  
                for(int j  = a[i].l;j <= a[i].r;++ j) { 
                    int p = find(edge[j].u),q = find(edge[j].v);
                    if(p != q) fa[p] = q; 
                }
            }
            printf("%d
    ",ans); 
        }
        return 0; 
    }
    
    
  • 相关阅读:
    PageObject小结
    python函数默认参数坑
    编译Android 8.0系统 并刷入pixel
    CF 289 F. Progress Monitoring DP计数
    EDU 61 F. Clear the String 区间dp
    Educational Codeforces Round 55 G 最小割
    Educational Codeforces Round 55 E 分治
    hdu 6430 bitset暴力
    AC自动机+DP codeforces86C
    CF895C dp/线性基
  • 原文地址:https://www.cnblogs.com/sssy/p/9008526.html
Copyright © 2011-2022 走看看