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

    传送门

    正解矩阵树

    不会

    显然最小生成树每个长度的边的数量是不变的

    而且题目说:具有相同权值的边不会超过10条。

    暴力 dfs 枚举所有相同长度的边,看看有多少种方案

    然后就过了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    struct edge
    {
        int a,b,v;
    }e[1005];//存边
    inline bool cmp(const edge a,const edge b){return a.v<b.v;}
    struct node
    {
        int l,r,s;
    }d[1005];//存排序后每个长度的边的左右边界和在最小生成树中的总数
    int n,m,cnt,ans=1,sum;
    
    int fa[105];
    inline int find(int x){ return fa[x]==x ? x : fa[x]=find(fa[x]); }
    inline void dfs(int i,int j,int s)
    {
        if(j>d[i].r){ if(s==d[i].s) sum++; return; }//如果到边界了就判断一波是否符合要求
        int xa=find(e[j].a),xb=find(e[j].b);
        if(xa!=xb)//如果可以加入就考虑加入
        {
            fa[xa]=xb;//更新一波并查集
            dfs(i,j+1,s+1);
            fa[xa]=xa;//恢复并查集
        }
        dfs(i,j+1,s);//考虑不加入的情况
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].v);
        //以下为最小生成树模板
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=n;i++) fa[i]=i;
        int res=0;
        for(int i=1;i<=m;i++)
        {
            if(e[i].v>e[i-1].v)//顺便计算一下d数组
                d[++cnt].l=i,d[cnt-1].r=i-1;
            int xa=find(e[i].a),xb=find(e[i].b);
            if(xa==xb) continue;
            d[cnt].s++; fa[xa]=xb; res++;
        }
        d[cnt].r=m;
        if(res<n-1){ cout<<"0"; return 0; }//判断一波
    
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<=cnt;i++)
        {
            sum=0;
            dfs(i,d[i].l,0);//强行dfs找方案
            ans=(ans*sum)%31011;
            for(int j=d[i].l;j<=d[i].r;j++)
            {
                int xa=find(e[j].a),xb=find(e[j].b);//更新一波状态
                if(xa==xb) continue;
                fa[xa]=xb;
            }
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    解决duplicate symbols for architecture x86_64错误
    IOS-UITextField键盘不隐藏问题
    IOS-细节错误
    IOS开发-图片上传
    IOS-指定返回Modal的控制器presentViewController
    支付-支付宝集成
    真机测试-Please enter a different string错误解决
    Xcode插件安装 错选了Skip Bundle解决办法
    SQLServer 命令批量删除数据库中指定表(游标循环删除)
    SQL中使用update inner join和delete inner join
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9721081.html
Copyright © 2011-2022 走看看