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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016

    做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如果有一种方案中权值为666的边有233条,那么另一种方案一定也是这样,并且它们在图中对连通性的影响也是相同的。

    于是我们先求出一种方案,记录下每种权值的边对应的数量。然后把权值相同的边分为一组,对于每一组搜索选出边的合法方案,乘法原理一下答案就出来了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int mod=31011;
     6 int inline readint(){
     7     int Num;char ch;
     8     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
     9     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    10     return Num;
    11 }
    12 int n,m;
    13 struct EDGE{
    14     int u,v,w;
    15 }e[2010],a[1010];
    16 int cnt=0,tot=0;
    17 bool cmp(EDGE a,EDGE b){
    18     return a.w<b.w;
    19 }
    20 int fa[110];
    21 int getfa(int x){
    22     return fa[x]==x?x:getfa(fa[x]);
    23 }
    24 int sum=0;
    25 void dfs(int x,int pos,int k){
    26     if(pos==a[x].v+1){
    27         if(k==a[x].w) sum++;
    28         return;
    29     }
    30     int fu=getfa(e[pos].u),
    31         fv=getfa(e[pos].v);
    32     if(fu!=fv){
    33         fa[fu]=fv;
    34         dfs(x,pos+1,k+1);
    35         fa[fu]=fu;
    36         fa[fv]=fv;
    37     }
    38     dfs(x,pos+1,k);
    39 }
    40 int main(){
    41     n=readint();
    42     m=readint();
    43     for(int i=1;i<=m;i++){
    44         e[i].u=readint();
    45         e[i].v=readint();
    46         e[i].w=readint();
    47     }
    48     sort(e+1,e+1+m,cmp);
    49     for(int i=1;i<=n;i++) fa[i]=i;
    50     for(int i=1;i<=m;i++){
    51         if(e[i].w!=e[i-1].w){
    52             a[cnt].v=i-1;
    53             a[++cnt].u=i;
    54         }
    55         int fu=getfa(e[i].u),
    56             fv=getfa(e[i].v);
    57         if(fu!=fv){
    58             fa[fu]=fv;
    59             a[cnt].w++;
    60             tot++;
    61         }
    62     }
    63     a[cnt].v=m;
    64     if(tot!=n-1){
    65         puts("0");
    66         return 0;
    67     }
    68     for(int i=1;i<=n;i++) fa[i]=i;
    69     int ans=1;
    70     for(int i=1;i<=cnt;i++){
    71         sum=0;
    72         dfs(i,a[i].u,0);
    73         ans=ans*sum%mod;
    74         for(int j=a[i].u;j<=a[i].v;j++){
    75             int fu=getfa(e[j].u),
    76                 fv=getfa(e[j].v);
    77             if(fu!=fv) fa[fu]=fv;
    78         }
    79     }
    80     printf("%d
    ",ans);
    81     return 0;
    82 }
  • 相关阅读:
    C++ Primer Plus 第15章 友元、异常和其它
    03013_JDBC工具类
    python GUI编程(Tkinter)
    Python2.x与3​​.x版本区别
    【python教程】Python JSON
    【python教程】Python IDE
    通过Google Custom Search API 进行站内搜索
    支持wmv、mpg、mov、avi格式的网页视频播放代码
    编写更好的jQuery代码的建议
    KindEditor得不到textarea值的解决方法
  • 原文地址:https://www.cnblogs.com/halfrot/p/7475516.html
Copyright © 2011-2022 走看看