zoukankan      html  css  js  c++  java
  • BZOJ 1016 [JSOI2008]最小生成树计数(kruskal + dfs)

    题意:

    求最小生成树的个数

    思路:

    网上很多题解都是矩阵树,

    由克鲁斯卡尔的步骤可以知道mst的每一种边权选的条数是固定的,所以我们dfs具体每种权值选哪几条并不会成环的方案数,相乘即可

    dfs是参考网上的,我是不会的


    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 998244353;
    const int maxn = 2e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int fa[1000 + 10];
    struct Edge{
        int u, v, w;
    }edge[1000 + 10];
    struct Node{
        int l ,r, num;
    }node[1000 + 10];
    int find(int x){
        return fa[x]==x?x:find(fa[x]);
    }
    
    bool cmp(Edge a, Edge b){
        return a.w < b.w;
    }
    int tol;
    int n, m;
    int cnt = 0;
    ll sum = 0;
    
    void init(){
        for(int i = 1; i <= n; i++){
            fa[i] = i;
        }
        return;
    }
    
    void dfs(int nodeid, int edgeid, int num){
        if(edgeid > node[nodeid].r){
            if(num==node[nodeid].num)sum++;
            return;
        }
        int u = edge[edgeid].u;
        int v = edge[edgeid].v;
        int t1 = find(u);
        int t2 = find(v);
        if(t1 != t2){
            fa[t1]=t2;
            dfs(nodeid, edgeid+1, num+1);//选这条边
            fa[t1]=t1; //改回去
            fa[t2]=t2;
        }
        dfs(nodeid, edgeid+1, num); //不选这条边
        return;
    }
    
    int main(){
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= m; i++){
            scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w);
        }
        sort(edge + 1, edge + 1 + m, cmp);
        ll ans = 1;
        init();
        tol = 0;
        cnt = 0;
        for(int i = 1; i <= m; i++){
            if(i==1 || edge[i].w != edge[i-1].w){
                node[cnt++].r = i-1;
                node[cnt].l = i;
                node[cnt].num = 0;
            }
            int u = edge[i].u;
            int v = edge[i].v;
            int t1 = find(u);
            int t2 = find(v);
            if(t1 != t2){
                fa[t1] = t2;
                node[cnt].num++;
                tol++;
            }
        }
        node[cnt].r = m;
        if(tol != n-1){
            printf("0");
            return 0;
        }
        init();
        for(int i = 1; i <= cnt; i++){
            sum = 0;
            dfs(i, node[i].l, 0);
            ans*=sum;
            ans%=31011;
    
            //最后是改回去的,所以得把这个权值的连回来
            for(int j = node[i].l; j <= node[i].r; j++){
                int u = edge[j].u;
                int v = edge[j].v;
                int t1 = find(u);
                int t2 = find(v);
                if(t1 != t2){
                    fa[t1] = t2;
                }
            }
        }
        printf("%lld
    ", ans);
        return 0;
    
    }
    /*
    10
    1 3 5 -1 5 7 -5 9 -1 1
    
    9
    2 3 5 2 1 6 4 2 3
     */
  • 相关阅读:
    使用 git 提交报错:error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large 的解决办法
    vue3使用 svg, 不是 svg 图标,是 svg 大图片。可动态修改参数
    Unix信号列表
    Linux CentOS系统安装 node 版本管理工具 nvm
    《能源监测与评价》——产品能耗的节能监测
    脚本
    Parallels Desktop 安装 Centos 虚拟机
    Nuxt3 学习笔记
    电力行业中的一些基本概念
    管理成熟度和管理者成熟度
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9833305.html
Copyright © 2011-2022 走看看