zoukankan      html  css  js  c++  java
  • BZOJ 1016 最小生成树计数

    今天真是一点调题的心情都没有呢~粘hzwer学长的模板。

    我们注意到每种权值的边在最小生成树内的个数总会是一样的。再看到不超过10个,暴力dfs即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define mod 31011
    using namespace std;
    int n,m,cnt,tot,ans=1,sum;
    int fa[105];
    struct edge{int x,y,v;}e[1005];
    struct data{int l,r,v;}a[1005];
    inline int read()
    {
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
    }
    bool cmp(edge a,edge b){return a.v<b.v;}
    int find(int x){return x==fa[x]?x:find(fa[x]);}
    void dfs(int x,int now,int k)
    {
    if(now==a[x].r+1)
    {
    if(k==a[x].v)sum++;
    return;
    }
    int p=find(e[now].x),q=find(e[now].y);
    if(p!=q)
    {
    fa[p]=q;
    dfs(x,now+1,k+1);
    fa[p]=p;fa[q]=q;
    }
    dfs(x,now+1,k);
    }
    int main()
    {
    n=read();m=read();
    for(int i=1;i<=n;i++)
    fa[i]=i;
    for(int i=1;i<=m;i++)
    e[i].x=read(),e[i].y=read(),e[i].v=read();
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
    if(e[i].v!=e[i-1].v){a[++cnt].l=i;a[cnt-1].r=i-1;}
    int p=find(e[i].x),q=find(e[i].y);
    if(p!=q){fa[p]=q;a[cnt].v++;tot++;}
    }
    a[cnt].r=m;
    if(tot!=n-1){printf("0");return 0;}
    for(int i=1;i<=n;i++)
    fa[i]=i;
    for(int i=1;i<=cnt;i++)
    {
    sum=0;
    dfs(i,a[i].l,0);
    ans=(ans*sum)%mod;
    for(int j=a[i].l;j<=a[i].r;j++)
    {
    int p=find(e[j].x),q=find(e[j].y);
    if(p!=q)fa[p]=q;
    }
    }
    printf("%d",ans);
    return 0;
    }

  • 相关阅读:
    sprint 1 的总结
    2016-11-23(第十天)
    2016-11-22(第九天)
    2016-11-20(第七天)
    2016-11-19(第六天)
    2016-11-18(第五天)
    sprint1_11.15燃尽图(第二天)
    OrderSys---Spring 计划(第一天)
    团队信息
    Scrum 4.0
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5224738.html
Copyright © 2011-2022 走看看