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

    现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。

    跑一遍克鲁斯卡尔,记录每种权值的边有多少条,然后状压枚举满足条件的所有边乘到答案中即可

    /**************************************************************
        Problem: 1016
        User: walfy
        Language: C++
        Result: Accepted
        Time:68 ms
        Memory:1452 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double g=10.0,eps=1e-12;
    const int N=1000+10,maxn=200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    struct edge{
        int u,v,c;
        bool operator<(const edge &rhs)const{
            return c<rhs.c;
        }
    }e[N];
    map<int,int>ans,id;
    vector<pii>v[N];
    int fa[N],prefa[N];
    int Find(int x)
    {
        return fa[x]==x?x:fa[x]=Find(fa[x]);
    }
    int main()
    {
        fio;
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)fa[i]=i;
        int cnt=0;
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            e[i]={a,b,c};
        }
        sort(e,e+m);
        for(int i=0;i<m;i++)
        {
            if(!id[e[i].c])id[e[i].c]=++cnt;
            v[id[e[i].c]].pb(mp(e[i].u,e[i].v));
            int x=e[i].u,y=e[i].v;
            int fx=Find(x),fy=Find(y);
            if(fx!=fy)fa[fx]=fy,ans[e[i].c]++;
        }
        for(int i=2;i<=n;i++)
            if(Find(i)!=Find(i-1))
            {
                cout<<0<<"
    ";
                return 0;
            }
        for(int i=1;i<=n;i++)fa[i]=i;
        map<int,int>::iterator it=id.begin();
        ll res=1;
        for(;it!=id.end();it++)
        {
            for(int i=1;i<=n;i++)prefa[i]=fa[i];
    //        for(int i=0;i<v[it->se].size();i++)printf("%d %d %d
    ",i,v[it->se][i].fi,v[it->se][i].se);
    //        puts("");
            ll len=v[it->se].size(),go=-1,pp=0;
            for(int i=0;i<(1<<len);i++)
            {
                int num=0;
                for(int j=0;j<len;j++)
                    if((i>>j)&1)
                        num++;
                if(num!=ans[it->fi])continue;
                else
                {
     
                    bool ok=1;
                    for(int j=0;j<len;j++)
                    {
                        if((i>>j)&1)
                        {
                            int x=v[it->se][j].fi,y=v[it->se][j].se;
                            int fx=Find(x),fy=Find(y);
                            if(fx!=fy)fa[fx]=fy;
                            else ok=0;
                        }
                    }
                    if(ok)pp++,go=i;//,printf("%d
    ",i);
                }
                for(int j=1;j<=n;j++)fa[j]=prefa[j];
            }
    //        printf("%d
    ",pp);
            res=(res*pp)%31011;
            if(go==-1)continue;
            for(int j=0;j<len;j++)
            {
                if((go>>j)&1)
                {
                    int x=v[it->se][j].fi,y=v[it->se][j].se;
                    int fx=Find(x),fy=Find(y);
                    if(x!=y)fa[fx]=fy;
                }
            }
        }
        cout<<res<<"
    ";
        return 0;
    }
    /***********************
    4 6
     
    1 2 1
     
    1 3 1
     
    1 4 1
     
    2 3 2
     
    2 4 1
     
    3 4 3
    ***********************/
    View Code
  • 相关阅读:
    进程虚拟内存
    非连续内存区缺页异常处理
    请求调页和写时复制
    标签对齐(补充)
    shell数学表达式
    缺页异常的处理
    不错的书籍
    imag database2
    image database
    Apache down了?
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8848137.html
Copyright © 2011-2022 走看看