• POJ 2784 Buy or Build 最小生成树


    枚举方案后做最小生成树。

    ------------

    const int maxn=1100;
    const int maxm=10000;
    int n,q;
    vector<int>g[10];
    int c[10];
    struct Point{
        int x,y;
        int getValueTo(Point p){
            return (p.x-x)*(p.x-x)+(p.y-y)*(p.y-y);
        }
    }p[maxn];
    struct EDGE{
        int u,v,d;
        bool operator<(const EDGE& rhs) const{
            return d<rhs.d;
        }
    }e[maxn*maxn];
    int edge;
    int pa[maxn];
    void makeset(int n){
        for (int i=0;i<=n;i++) pa[i]=i;
    }
    int findset(int x){
        if (x!=pa[x]) pa[x]=findset(pa[x]);
        return pa[x];
    }
    bool unionset(int x,int y){
        x=findset(x);
        y=findset(y);
        if (x!=y) {
            pa[x]=y;
            return true;
        }
        return false;
    }
    int kruskal(){
        int ans=0;
        for (int i=0;i<edge;i++){
            if (unionset(e[i].u,e[i].v)){
                ans+=e[i].d;
            }
        }
        return ans;
    }
    int main(){
    	while (~scanf("%d%d",&n,&q)){
            for (int i=0;i<q;i++){
                int cnt;
                scanf("%d%d",&cnt,&c[i]);
                for (int j=0;j<cnt;j++){
                    int tmp;
                    scanf("%d",&tmp);
                    g[i].push_back(tmp);
                }
            }
            for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
            edge=0;
            for (int i=1;i<=n;i++){
                for (int j=i+1;j<=n;j++){
                    e[edge].u=i;
                    e[edge].v=j;
                    e[edge++].d=p[i].getValueTo(p[j]);
                }
            }
            sort(e,e+edge);
            makeset(n);
            int ans=kruskal();
            for (int s=1;s<(1<<q);s++){
                makeset(n);
                int cost=0;
                for (int i=0;i<q;i++){
                    if (s&(1<<i)){
                        cost+=c[i];
                        for (int j=1;j<sz(g[i]);j++){
                            unionset(g[i][j-1],g[i][j]);
                        }
                    }
                }
                ans=min(ans,cost+kruskal());
            }
            printf("%d
    ",ans);
    	}
    	return 0;
    }
    


    ------------

  • 相关阅读:
    77. Combinations
    76. Minimum Window Substring
    75. Sort Colors
    74. Search a 2D Matrix
    73. Set Matrix Zeroes
    72. Edit Distance
    71. Simplify Path
    70. Climbing Stairs
    线段树+欧拉函数——cf1114F
    区间dp——好题cf1132F
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681520.html
Copyright © 2020-2023  润新知