zoukankan      html  css  js  c++  java
  • bzoj1016

    题解:

    首先用最小生成树的方法来做一遍

    然后枚举一下一些边可以被哪些边来替换

    乘法原理计算总和

    代码:

    #include<bits/stdc++.h>
    const int M=31011;
    using namespace std;
    int n,m,cnt,tot,ans=1,sum,fa[105];
    struct edge
    {
        int x,y,z;
    }e[1005];
    struct data
    {
        int l,r,v;
    }a[1005];
    bool cmp(edge a,edge b)
    {
        return a.z<b.z;
    }
    int find(int x)
    {
        return x==fa[x]?x:find(fa[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(e[now].x),q=find(e[now].y);
         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()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)fa[i]=i;
        for (int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
        sort(e+1,e+m+1,cmp);
        for (int i=1;i<=m;i++)
         {
            if(e[i].z!=e[i-1].z){a[++cnt].l=i;a[cnt-1].r=i-1;}
            int p=find(e[i].x),q=find(e[i].y);
            if(p!=q){fa[p]=q;a[cnt].v++;tot++;}
         }
        a[cnt].r=m;
        if(tot!=n-1)
         {
             puts("0");
            return 0;
         }
        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)%M;
            for(int j=a[i].l;j<=a[i].r;j++)
             {
                int p=find(e[j].x),q=find(e[j].y);
                if(p!=q)fa[p]=q;
             }
         }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    理解MapReduce计算构架
    熟悉HBase基本操作
    爬虫大作业
    第三章 熟悉常用的HDFS操作
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    Hadoop综合大作业
    hive基本操作与应用
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7683992.html
Copyright © 2011-2022 走看看