• uva1151并查集+最小生成树


    并查集+最小生成树

    链接:https://www.luogu.com.cn/problem/UVA1151

    先过一次kruskal,然后枚举所有的可能性找最小值

    代码:

    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #define ll long long
    using namespace std;
    const int maxn=1050;
    int fa[maxn];
    struct Edge{
        int u,v;
        int w;
        bool operator < (const Edge&ch )const
        {
            return w<ch.w;
        }
    }a[maxn*maxn];
    struct node{
        int x,y;
    }v[maxn];
    int total;
    vector<int> g[10];
    int V[maxn];
    void init(){
        for(int i=1; i<=maxn; i++) fa[i]=i;
    }
    int get(node a,node b){
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    int Find(int x){
        int r=x;
        while(r!=fa[r]){
            r=fa[r];
        }
        int j=x;
        while(fa[j]!=r){
            int i=fa[j];
            fa[j]=r;
            j=i;
        }
        return r;
    }
    int kruskal(){
        int ss=0;
        for(int i=1; i<=total; i++){
            int fx=Find(a[i].u);
            int fy=Find(a[i].v);
            if(fx!=fy){
                ss+=a[i].w;
                fa[fx]=fy;
            }
        }
        return ss;
    }
    
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int num;
           int n,q;
            memset(V,0,sizeof(V));
            scanf("%d%d",&n,&q);
            for(int i=0; i<=q; i++) g[i].clear();
            for(int i=0; i<q; i++){
                int x;
                scanf("%d%d",&num,&V[i]);
                for(int j=1; j<=num; j++){
                    scanf("%d",&x);
                    g[i].push_back(x);
                }
            }
            for(int i=1; i<=n; i++){
                scanf("%d%d",&v[i].x,&v[i].y);
            }
            total=0;
            for(int i=1; i<=n; i++){
                for(int j=i+1; j<=n; j++){
                    total++;
                    a[total].u=i; a[total].v=j;
                    a[total].w=get(v[i],v[j]);
                }
            }
            init();
            sort(a+1,a+1+total);
            int sum=kruskal();
            int c;
            for(int i=0; i<(1<<q); i++){
                init();
                c=0;
                for(int j=0; j<q; j++)
                {
                    if(i & (1<<j)){//确保进行的次数只有(1<<q)次
                        c+=V[j];
                        int xx=Find(g[j][0]);
                        for(int k=1; k<g[j].size(); k++){
                            int xy=Find(g[j][k]);
                            if(xx!=xy){
                                fa[xy]=xx;
                            }
                        }
                    }
                }
                sum=min(c+kruskal(),sum);
            }
            printf("%d
    ",sum);
            if(t) printf("
    ");
        }
        return 0;}
  • 相关阅读:
    初探 Redis 客户端 Lettuce:真香!
    vscode 代码中查找并替换为换行符
    Jenkins Kubernetes插件添加 云
    Jenkins kubernetes插件的原理
    jenkins pipeline实现自动构建并部署至k8s
    python3 requests中的 stream参数
    rsync 开启用户密码认证
    rancher1版本 基本使用
    nginx http跳https
    sed合并多条指令修改文本
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/12577134.html
Copyright © 2020-2023  润新知