zoukankan      html  css  js  c++  java
  • hihocoder #1160 : 攻城略地

    描述

    A、B两国间发生战争了,B国要在最短时间内对A国发动攻击。已知A国共有n个城市(城市编号1, 2, …, n),城市间有一些道路相连。每座城市的防御力为w,直接攻下该城的代价是w。若该城市的相邻城市(有道路连接)中有一个已被占领,则攻下该城市的代价为0。

    除了占领城市,B国还要摧毁A国的交通系统,因而他们需要破坏至少k条道路。由于道路损毁,攻下所有城市的代价相应会增加。假设B国可以任意选择要摧毁的道路,那么攻下所有城市的最小代价是多少?

    解题报告:
    用时:1h30min
    正解:贪心
    首先要看懂题目:要使得去掉k条边后每一个联通块最小值之和最小,那么就简单了,直接贪心:我们要将权值小的贡献尽量多,所以我们可以先使得整个图连通,然后选择最小的几个作为最小值,单独成连通块,并查集维护即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=1e6+5;
    int val[N],n,m,k,fa[N],v[N],q[N],kase=0;
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    void work()
    {
    	int x,y,cnt=0;
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&val[i]),fa[i]=i,v[i]=val[i];
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&x,&y);
    		if(find(x)==find(y)){k--;continue;}
    		if(v[find(x)]<v[find(y)])swap(x,y);
    		v[find(x)]=v[find(y)];
    		fa[find(x)]=find(y);
    	}
    	long long ans=0;
    	for(int i=1;i<=n;i++)
    		if(fa[i]==i)ans+=v[i];
    		else q[++cnt]=val[i];
    	sort(q+1,q+cnt+1);
    	for(int i=1;i<=k;i++)ans+=q[i];
    	printf("Case #%d: %lld
    ",++kase,ans);
    }
    
    int main()
    {
    	int T;cin>>T;
    	while(T--)work();
    	return 0;
    }
    
    
  • 相关阅读:
    Struts2 helloWorld
    Python学习笔记基础汇总部分
    从控制台读入,典型的装饰者模式
    随机数产生方法小知识点
    Struts2基础知识
    面向对象原则之GOF是招式,九大原则才是精髓
    静态工厂方法
    单例模式singleton
    J2SE基础夯实系列之JDBC,链接数据库实例代码
    Ubuntu 12.04 下安装ssh 服务遇到的问题以及总结
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7573715.html
Copyright © 2011-2022 走看看