• bzoj1016题解


    【解题思路】

      Kruskal的拓展。

      可以先对边排序,进行一次Kruskal,判断是否可行,并计算出每种权值的边需要多少条。

      然后暴力统计每种权值可行的方案数,根据乘法原理乘起来即可。复杂度o(210mlog2(m+α(n)))。

    【参考代码】

     1 #pragma GCC optimize(2)
     2 #include <algorithm>
     3 #define REP(i,low,high) for(register int i=(low);i<=(high);++i)
     4 using namespace std;
     5  
     6 //quick_io {
     7 #include <cctype>
     8 #include <cstdio>
     9 inline long long getint()
    10 {
    11     char ch=getchar(); for(;!isdigit(ch)&&ch!='+'&&ch!='-';ch=getchar());
    12     short sig=1; for(;ch=='+'||ch=='-';ch=getchar()) if(ch=='-') sig*=-1;
    13     long long ret=0; for(;isdigit(ch);ch=getchar()) ret=(ret<<3)+(ret<<1)+ch-'0';
    14     return sig*ret;
    15 }
    16 //} quick_io
    17  
    18 //find_union_set {
    19 #include <cstring>
    20 class find_union_set
    21 {
    22 private:int fat[110],stk[110];
    23     int find(const int&element)
    24     {
    25         int ancestor=element,top=0;
    26         for(;ancestor!=fat[ancestor];ancestor=fat[ancestor]) stk[top++]=ancestor;
    27         for(;top--;fat[stk[top]]=ancestor); return ancestor;
    28     }
    29 public:
    30     find_union_set() {REP(i,1,100) fat[i]=i;} void clear() {REP(i,1,100) fat[i]=i;}
    31     find_union_set&operator=(const find_union_set&thr)
    32     {
    33         return memcpy(fat,thr.fat,sizeof thr.fat),*this;
    34     }
    35     bool same(const int&one,const int&thr) {return find(one)==find(thr);}
    36     bool unite(const int&one,const int&thr)
    37     {
    38         return same(one,thr)?0:(fat[fat[one]]=fat[thr],1);
    39     }
    40 };
    41 //} find_union_set
    42  
    43 struct edge
    44 {
    45     int fr,to,vl;
    46     void input() {fr=getint(),to=getint(),vl=getint();}
    47     bool operator<(const edge&thr)const{return vl<thr.vl;}
    48 }edg[1010];
    49  
    50 static const int AwD=31011; int cnt[1010]={0}; find_union_set now,tmp,can;
    51 int main()
    52 {
    53     int n=getint(),m=getint(); REP(i,1,m) edg[i].input(); sort(edg+1,edg+m+1);
    54     int tot=0,ans=1; REP(i,1,m)
    55     {
    56         tot+=edg[i].vl!=edg[i-1].vl;
    57         if(!now.same(edg[i].fr,edg[i].to)) now.unite(edg[i].fr,edg[i].to),++cnt[tot];
    58     }
    59     REP(i,2,n) if(!now.same(1,i)) return puts("0"),0; now.clear();
    60     for(register int i=1,j=1,tot=1;i<=m;i=++j,++tot,now=can)
    61     {
    62         for(;j<=m&&edg[j].vl==edg[i].vl;++j); --j; int count=0;
    63         for(register int status=1<<j-i+1;status--;)
    64         if(__builtin_popcount(status)==cnt[tot])
    65         {
    66             tmp=now; bool flag=0; REP(k,i,j) if(status&(1<<k-i))
    67             {
    68                 if(flag=!tmp.unite(edg[k].fr,edg[k].to)) break;
    69             }
    70             if(!flag) {can=tmp; if(++count==AwD) count=0;}
    71         }
    72         (ans*=count)%=AwD;
    73     }
    74     return printf("%d
    ",ans),0;
    75 }
    View Code
    We Secure, We Contain, We Protect.
  • 相关阅读:
    PHP运行模式
    深入理解php内核 编写扩展_III- 资源
    深入理解php内核 编写扩展 II:参数、数组和ZVALs
    [置顶] 图灵电子与电气工程丛书
    PHP开发-上传文件
    DWZ (JUI) 教程(二):处理信息回馈的通用规范
    设计模式之装饰者模式
    UVA 11464
    uva 1346
    [置顶] 手把手教你iOS消息推送证书生成以及Push消息
  • 原文地址:https://www.cnblogs.com/spactim/p/6433008.html
Copyright © 2020-2023  润新知