• bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)


    由于有相同权值的边不超过10条的限制,所以可以暴搜

    先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下)

    可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的、而且它们连成的连通块也是一样的

    所以我们把每个权值的边分开暴搜所有可能的情况,最后再乘到一起就是答案

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=110,maxm=1010,P=31011;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 struct Edge{
    16     int a,b;
    17     ll l;
    18 }eg[maxm];
    19 int egh[maxn],ect;
    20 int N,M,L,cnt[maxm];
    21 int fa[maxn],ans,sum;
    22 
    23 inline bool cmp(Edge a,Edge b){return a.l<b.l;}
    24 inline int getf(int x){
    25     while(x!=fa[x]) x=fa[x];return x;
    26 }
    27 
    28 void dfs(int x,int y,int n){
    29     if(x>M||eg[x].l!=y){
    30         if(n==cnt[y]) sum=(sum+1)%P;
    31         return;
    32     }
    33     int aa=getf(eg[x].a),bb=getf(eg[x].b);
    34     if(aa!=bb){
    35         fa[aa]=bb;
    36         dfs(x+1,y,n+1);
    37         fa[aa]=aa;
    38     }
    39     dfs(x+1,y,n);
    40 }
    41 
    42 int main(){
    43     //freopen("","r",stdin);
    44     int i,j,k;
    45     N=rd(),M=rd();
    46     for(i=1;i<=M;i++){
    47         eg[i].a=rd(),eg[i].b=rd();
    48         eg[i].l=rd();
    49     }sort(eg+1,eg+M+1,cmp);
    50     int lst=-1;
    51     for(i=1,j=0;i<=M;i++){
    52         if(eg[i].l!=lst) j++;
    53         lst=eg[i].l,eg[i].l=j;
    54     }
    55     for(i=1;i<=N;i++) fa[i]=i;
    56     for(i=1,j=0;i<=M;i++){
    57         int x=getf(eg[i].a),y=getf(eg[i].b);
    58         if(x!=y){
    59             fa[x]=y;
    60             j++;cnt[eg[i].l]++;
    61         }
    62     }
    63     if(j<N-1){printf("0
    ");return 0;}
    64     for(i=1;i<=N;i++) fa[i]=i;
    65     int ans=1;
    66     for(i=1,j=0;i<=M;i++){
    67         if(eg[i].l!=eg[i-1].l){
    68             sum=0;dfs(i,eg[i].l,0);
    69             ans=(ans*sum)%P;
    70         }
    71         int x=getf(eg[i].a),y=getf(eg[i].b);
    72         if(x!=y){
    73             fa[x]=y;j++;
    74         }
    75     }
    76     printf("%d
    ",ans);
    77     return 0;
    78 }
  • 相关阅读:
    Find the most frequent element in all intervals
    1365. How Many Numbers Are Smaller Than the Current Number
    CodeForces 1316C
    CodeForces-1305D Kuroni and the Celebration【树】
    CodeForces-1305C Kuroni and Impossible Calculation【思维】
    CodeForces 1254D Tree Queries【树链剖分+树状数组】
    Scout YYF I POJ
    CodeForces-1320C World of Darkraft: Battle for Azathoth 【权值线段树+思维】
    主席树总结
    Codeforces 1320A Journey Planning【思维转换】
  • 原文地址:https://www.cnblogs.com/Ressed/p/9758794.html
Copyright © 2020-2023  润新知