zoukankan      html  css  js  c++  java
  • tyvj2054 四叶草魔杖——连通块 & 状压DP

    题目:http://www.joyoi.cn/problem/tyvj-2054

    把点分成几个连通块,和为0的几个点放在一块,在块内跑最小生成树作为这个块的代价;

    然后状压DP,组成全集的最小代价就是答案;

    1A了好高兴!

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,a[20],hd[20],ct,f[1<<20],cnt,fa[20],inf=0x3f3f3f3f,g[1<<20],tot;
    bool vis[20];
    struct N{
        int u,v,w;
        N(int t=0,int n=0,int w=0):u(t),v(n),w(w) {}
    }e[205];
    bool cmp(N x,N y){return x.w<y.w;}
    int calc(int g)
    {
        int sum=0;
        for(int i=1;i<=n;i++) if(g&(1<<(i-1)))sum+=a[i];
        return sum;
    }
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int kruskal(int g)
    {
        int num=0,ret=0;
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n;i++)
        {
            fa[i]=i;
            if(g&(1<<(i-1)))vis[i]=1,num++;
        }
        int t=0;
        for(int i=1;i<=m;i++)
        {
            if(!vis[e[i].u]||!vis[e[i].v])continue;
            int u=find(e[i].u),v=find(e[i].v);
            if(u!=v)
            {
                fa[u]=v; ret+=e[i].w; t++;
                if(t==num-1)break;
            }
        }
        if(t!=num-1)return inf;
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w),e[i].u++,e[i].v++;
        sort(e+1,e+m+1,cmp);
        memset(f,0x3f,sizeof f);
        for(int i=1;i<=(1<<n)-1;i++)
            if(calc(i)==0)
            {
                int ff=kruskal(i);
                if(ff!=inf)g[++tot]=i,f[i]=ff;
            }
        f[0]=0;
        for(int i=0;i<=(1<<n)-1;i++)
        {
            for(int j=1;j<=tot;j++)
                if((i&g[j])==0)f[i|g[j]]=min(f[i|g[j]],f[i]+f[g[j]]);
        }
        if(f[(1<<n)-1]==inf)printf("Impossible
    ");
        else printf("%d
    ",f[(1<<n)-1]);
        return 0;
    }
  • 相关阅读:
    将博客搬至CSDN
    defender 月考总结
    生日祝福@陈俊翰
    个性签名
    你这是virus吧?
    (CPSCA's)CPOJC+VIJOS
    Sentence by defender
    工作制一览
    最长上升子序列
    mysql约束
  • 原文地址:https://www.cnblogs.com/Zinn/p/9277018.html
Copyright © 2011-2022 走看看