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;
    }
    
    
  • 相关阅读:
    C#中KeyDown和KeyPress区别
    c#快捷键设置和text输入限制
    问题总结
    c#串口编程和单片机通信重大发现
    c#类似单片机的8bit或运算
    c#中将默认常量(32bit)转换为8bit
    我的秋季个人阅读计划
    学期总结
    阅读笔记《软件秘籍》03
    阅读笔记--09
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7573715.html
Copyright © 2011-2022 走看看