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;    
    }
  • 相关阅读:
    CentOS下编译安装hping3
    ping命令的几个简单使用
    安装CPqD/ofdissector遭遇的错误
    ldconfig报错 :libstdc++.so.6.0.18-gdb.py不是一个elf文件
    sudo source /etc/profile 提示找不到source命令
    linux下安装pkg-config时遇到"glib-2.0>=2.16"的错
    CentOS6.2编译安装codelite5.3
    Socket构造但不连接
    linux c——dup( )和dup2( )函数详解(转)
    Linux中重定向
  • 原文地址:https://www.cnblogs.com/invoid/p/5512697.html
Copyright © 2011-2022 走看看