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

    题解:

    我们可以知道每个不同的最小生成树对于一个边权所使用的数量都是相同的.
    那么我们就可以先做一次最小生成树,然后对于每一个最小生成树中的边权搜索出所有的可以选取的方案,然后乘法原理累计答案即可.

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstring>
     7 #include<queue>
     8 #include<vector>
     9 #define MAXN 500010
    10 #define RG register
    11 #define LL long long int
    12 using namespace std;
    13 const int INF=1e9;
    14 const int mod=31011;
    15 struct node{
    16   int x,y,w;
    17 }e[MAXN];
    18 int n,m;
    19 int fa[MAXN];
    20 int L[MAXN],R[MAXN],T[MAXN],cnt;
    21 int tot;
    22 int ans=1,sum;
    23 bool cmp(node a,node b){ return a.w<b.w;}
    24 int find(int x)
    25 {
    26   if(fa[x]==x) return x;
    27   else return find(fa[x]);
    28 }
    29 void dfs(int id,int now,int num)
    30 {
    31   if(now==R[id]+1)
    32     {
    33       if(num==T[id]) sum++;
    34       return;
    35     }
    36   int f1=find(e[now].x),f2=find(e[now].y);
    37   if(f1!=f2){
    38     fa[f2]=f1;
    39     dfs(id,now+1,num+1);
    40     fa[f1]=f1;fa[f2]=f2;
    41   }
    42   dfs(id,now+1,num);
    43 }
    44 int main()
    45 {
    46   freopen("1.in","r",stdin);
    47   scanf("%d%d",&n,&m);
    48   for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
    49   sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++) fa[i]=i;
    50   for(int i=1;i<=m;i++)
    51     {
    52       if(e[i].w!=e[i-1].w) R[cnt]=i-1,L[++cnt]=i;
    53       int f1=find(e[i].x),f2=find(e[i].y);
    54       if(f1!=f2){ fa[f2]=f1;T[cnt]++;tot++;}
    55     }
    56   R[cnt]=m;
    57   if(tot!=n-1){ printf("0
    ");return 0;}
    58   for(int i=1;i<=n;i++) fa[i]=i;
    59   for(int i=1;i<=cnt;i++){
    60     sum=0;
    61     dfs(i,L[i],0);
    62     (ans*=sum)%=mod;
    63     for(int j=L[i];j<=R[i];j++){
    64       int f1=find(e[j].x),f2=find(e[j].y);
    65       if(f1!=f2){ fa[f2]=f1;}
    66     }
    67   }
    68   printf("%d
    ",ans);
    69   return 0;
    70 }
  • 相关阅读:
    调试代码的技巧
    关联Lable和输入项
    如何更有效的利用自己的时间
    高效能人士的七个习惯>读书笔记之二
    .NET别名机制简介
    VS2005升SP1错误1718文件FileName被数字签名策略拒绝
    程序物语(三):做人、做事、生活
    程序物语(二):起手式
    SQL Server 2008如何压缩日志(log)文件?
    prototype中文参数乱码解决方案
  • 原文地址:https://www.cnblogs.com/Landlord-greatly/p/8082802.html
Copyright © 2011-2022 走看看