zoukankan      html  css  js  c++  java
  • [hiho1160] 攻城略地

    题意:给出一个图,每个点有一个权值,破坏这个点需要花费这个点的权值,你的任务是破坏所有的点,若破坏某个点之前它的相邻点已经被破坏,那么它就不需要花费代价,求破坏所有点的最小代价

    题解:

    带权并查集

    破坏一个点后,则这个点所在连通块的所有点就会被破坏,那么每个连通块都破坏其代价最小的点

    若破坏的边不足k,则从小到大破坏其他的点

    /*
      Attack
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    using namespace std;
    
    const int N = 1000010;
    
    int w[N],fa[N],q[N],v[N];
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    int find(int x) {
      return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    
    int main() {
      int T=gi(),tot=0;
      while(T--) {
        int n=gi(),m=gi(),k=gi(),cnt=0;
        for(int i=1; i<=n; i++) v[i]=w[i]=gi(),fa[i]=i;
        for(int i=1; i<=m; i++) {
          int x=gi(),y=gi(),xx,yy;
          xx=find(x),yy=find(y);
          if(xx==yy) {k--;continue;}
          if(w[xx]>w[yy]) swap(xx,yy);
          w[yy]=w[xx],fa[yy]=xx;
        }
        ll ans=0;
        for(int i=1; i<=n; i++) {
          if(i==fa[i]) ans+=w[i];
          else q[++cnt]=v[i];
        }
        sort(q+1,q+cnt+1);
        for(int i=1; i<=k; i++) ans+=q[i];
        printf("Case #%d: %lld
    ", ++tot,ans);
      }
      return 0;
    }
  • 相关阅读:
    线程中常见的方法
    停止线程方式
    线程间的通信_多生产者多消费者问题_JDK1.5新特性_Lock
    1-为什么java的main方法必须是静态的
    45-机器设计问题(深搜)
    44-最大差值三角形
    23-吝啬的国度(vector+深搜)
    43-八数码
    41-安排车辆
    41-邮差送信(dfs)
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7588241.html
Copyright © 2011-2022 走看看