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

    先做一遍kruskal,然后发现不同的方案只可能是相同权值的不同的边干了相同的事

    题目又保证了相同权值的边数很少,直接状压即可

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define N 1005
     7 using namespace std;
     8 int getnum(int x){
     9     int cnt=0;
    10     while(x){cnt+=x&1;x>>=1;}
    11     return cnt;
    12 }
    13 int n,m,ans=1;
    14 int fa[N],tmp[N];
    15 int find(int x,int *y){
    16     if(x==y[x])return x;
    17     return y[x]=find(y[x],y);
    18 }
    19 struct edge{int u,v,w;}ed[10*N];
    20 bool cmp(edge a,edge b){return a.w<b.w;}
    21 bool vis[10*N];
    22 int bit[15];
    23 int main(){
    24     bit[0]=1;
    25     for(int i=1;i<=10;i++)bit[i]=bit[i-1]<<1;
    26     scanf("%d%d",&n,&m);
    27     for(int i=1;i<=n;i++)fa[i]=i;
    28     for(int i=1;i<=m;i++)
    29         scanf("%d%d%d",&ed[i].u,&ed[i].v,&ed[i].w);
    30     sort(ed+1,ed+m+1,cmp);
    31     for(int i=1,fv,fu;i<=m;i++){
    32         fu=find(ed[i].u,fa);fv=find(ed[i].v,fa);
    33         if(fu!=fv){
    34             fa[fu]=fv;
    35             vis[i]=1;
    36         }
    37     }
    38     for(int be=1,en,num,len,cnt,flag;be<=m;be++){
    39         for(en=be;en<=m&&ed[en+1].w==ed[be].w;en++);
    40         for(int i=1;i<=n;i++)fa[i]=tmp[i]=i;
    41         num=n-1;cnt=0;
    42         for(int i=1;i<=m;i++){
    43             if(i>=be&&i<=en)continue;
    44             if(vis[i]){
    45                 int fu=find(ed[i].u,tmp),fv=find(ed[i].v,tmp);
    46                 tmp[fu]=fv;num--;
    47             }
    48         }
    49         len=en-be+1;
    50         for(int i=0;i<bit[len];i++)if(getnum(i)==num){
    51             flag=0;
    52             memcpy(fa,tmp,sizeof fa);
    53             for(int j=be;j<=en;j++){
    54                 if(i&bit[j-be]){
    55                     int fu=find(ed[j].u,fa),fv=find(ed[j].v,fa);
    56                     if(fu==fv){flag=1;break;}
    57                     fa[fu]=fv;
    58                 }
    59             }
    60             if(flag==0)cnt++;
    61         }
    62         ans=ans*cnt%31011;
    63         be=en;
    64     }
    65     printf("%d
    ",ans);
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    使用python,批量生产条形码
    excel——VlookUp函数的使用
    MQTT消息队列压力测试
    shell脚本中,关于if,以及条件判断
    linux下的echo
    python对文件操作 r w a 文件复制/修改
    使用Appium进行iOS的真机自动化测试
    pycharm 解决PEP8问题,配置autopep8到菜单栏
    Python中list的合并
    Centos最小化安装后,不能使用yum命令的解决办法
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8184653.html
Copyright © 2011-2022 走看看