zoukankan      html  css  js  c++  java
  • bzoj5038 四叶草魔杖

    很有意思的最小生成树啊。

    网上的题解大多是状压+最小生成树,经过我的试验,其实只要把每个联通块找出来,一个个做一次就可以了。

    放一个状压的。懒得再写一个搜索找联通块

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,m;
    struct edge{int x,y,d;}e[310];
    bool cmp(edge e1,edge e2){return e1.d<e2.d;}
    int fa[110000];
    int findfa(int x)
    {
        if(fa[x]==x)return x;
        fa[x]=findfa(fa[x]);return findfa(fa[x]);
    }
    int kruscal(int zt)
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
            if(zt&(1<<i-1))fa[i]=i,cnt++;
        if(cnt==1)return 0;
        
        int ans=0;
        for(int i=1;i<=m;i++)
            if((zt&(1<<e[i].x-1))&&(zt&(1<<e[i].y-1)))
            {
                int fx=findfa(e[i].x),fy=findfa(e[i].y);
                if(fx!=fy)
                {
                    fa[fx]=fy;
                    ans+=e[i].d;
                    cnt--;if(cnt==1)return ans;
                }
            }
        return (1<<30);
    }
    int c[30],sum[110000],f[110000];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&c[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d),e[i].x++,e[i].y++;
            if(e[i].x==e[i].y)i--,m--;
        }
        sort(e+1,e+m+1,cmp);
            
        int maxp=(1<<n)-1;
        for(int zt=1;zt<=maxp;zt++)
        {
            sum[zt]=0;
            for(int i=1;i<=n;i++)
                if(zt&(1<<(i-1)))sum[zt]+=c[i];
            if(sum[zt]==0)f[zt]=kruscal(zt);
        }
        for(int zt1=1;zt1<=maxp;zt1++) if(sum[zt1]==0&&f[zt1]!=(1<<30))
            for(int zt2=zt1+1;zt2<=maxp;zt2++) if(sum[zt2]==0&&f[zt2]!=(1<<30))
                if((!(zt1&zt2)))
                    f[zt1|zt2]=min(f[zt1|zt2],f[zt1]+f[zt2]);
        
        if(sum[maxp]!=0||f[maxp]==(1<<30))printf("Impossible
    ");
        else printf("%d
    ",f[maxp]);
        return 0;
    }
  • 相关阅读:
    Vue中computed和watch的区别
    JS基础语法
    JDBC
    表设计
    查询语句
    反射
    网络端
    多线程
    HashMap
    IO
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9546377.html
Copyright © 2011-2022 走看看