Destroy Walls

  Long times ago, there are beautiful historic walls in the city. These walls divide the city into many parts of area.
  Since it was not convenient, the new king wants to destroy some of these walls, so he can arrive anywhere from his castle. We assume that his castle locates at (0.6∗2–√,0.6∗3–√).
  There are n towers in the city, which numbered from 1 to n. The ith's location is (xi,yi). Also, there are m walls connecting the towers. Specifically, the ith wall connects the tower ui and the tower vi(including the endpoint). The cost of destroying the ith wall is wi.
  Now the king asks you to help him to divide the city. Firstly, the king wants to destroy as less walls as possible, and in addition, he wants to make the cost least.
  The walls only intersect at the endpoint. It is guaranteed that no walls connects the same tower and no 2 walls connects the same pair of towers. Thait is to say, the given graph formed by the walls and towers doesn't contain any multiple edges or self-loops.
  Initially, you should tell the king how many walls he should destroy at least to achieve his goal, and the minimal cost under this condition.

Input
  There are several test cases.
  For each test case:
  The first line contains 2 integer n, m.
  Then next n lines describe the coordinates of the points.
  Each line contains 2 integers xi,yi.
  Then m lines follow, the ith line contains 3 integers ui,vi,wi
  |xi|,|yi|≤105
  3≤n≤100000,1≤m≤200000
  1≤ui,vi≤n,ui≠vi,0≤wi≤10000

Output
  For each test case outout one line with 2 integers sperate by a space, indicate how many walls the king should destroy at least to achieve his goal, and the minimal cost under this condition.

Sample Input

4 4
-1 -1
-1 1
1 1
1 -1
1 2 1
2 3 2
3 4 1
4 1 2

Sample Output

1 1

解题思路:
  首先,很重要的一点,本题给出的所有坐标值都没用,都是吓人的。

  本题的意思是有一个城堡,被数条城墙分隔为多个区域,城墙的端点只会是塔楼,并且城墙只在端点相交,一条城墙的两端不会连在同一个塔楼上(图没有自环),拆除每个城墙都会有一定消耗,国王希望通过最少的消耗,使城堡所有区域都连通。

  本题有多组测试用例,每组测试用例包括,塔楼数量(端点数量)n, 城墙数量(边数)m,首先跟随n行,每行包括两个整数x y为塔楼的坐标(没用),之后m行跟随,每行包括三个整数,分别为城墙连接的两个塔楼u , v,拆毁该城墙的消耗w。

  要求输出使所有区域连通所需的最少的消耗。

  仔细思考一下就会发现,本题的最终要求就是让我们把给定的图通过抹去边变成无环图,而且抹去边的权值要尽可能的小。而将平面图变成无环图叫什么?——生成树!!

  提到生成树,我们想到两个算法Prim算法与Kruskal算法,因为本题可以通过将边由大到小排序求的最大生成树,在这里我们使用Kruskal算法。

kruskal算法核心思想:  

  既然已经给出了邻接表。初始视所有塔楼都为不连通(即拆除所有城墙),之后将城墙按消耗排序,从大到小枚举所有城墙,判断城墙两端的塔楼是否已经连通,若已经连通不做处理(即该墙需要拆除)拆除的墙数加一,若不连通则将该边记录入最大生成树(该墙无需拆除),并从拆毁所有城墙的总消耗里减去该城墙的消耗。

bool cmp(edge a, edge b){   //城墙排序为拆除消耗由大到小
return a.w > b.w;
}
LL kruskal(int n, int m, LL sum, int &cnt){ //kruskal算法
//由于需要改变cnt的值所以在这里cnt传引用
LL ans = sum; //传入的sum为拆除所有城墙所需的总消耗
for(int i = ; i <= n; i++){
father[i] = i; //初始化所有塔楼为不连通
}
sort(Edge + , Edge + + m, cmp); //城墙权值从大到小排序
for(int i = ; i <= m; i++){
int faNode1 = getFather(Edge[i].u);
int faNode2 = getFather(Edge[i].v);
if(faNode1 != faNode2){ //判断城墙连接的两个塔楼是否连通
father[faNode1] = faNode2; //不连通则标记为连通
ans -= Edge[i].w; //该城墙不需要拆数
}else{ //如果城墙两个端点塔楼已经连通则该城墙需要拆除
cnt++; //记录需要拆除的城墙数量
}
}
return ans; //返回的ans为拆除的最小消耗

kruskal

判断是否连通使用并查集

int father[maxn];
int getFather(int x)
{
if(father[x] == x)
return x;
else
return father[x] = getFather(father[x]); }

并查集

AC代码

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 2e5+;
struct edge{ //edge储存城墙
int u, v; //城墙连接的两个结点
LL w; //拆除的消耗
}Edge[maxn];
int father[maxn];
int getFather(int x) //并查集部分
{
if(father[x] == x)
return x;
else
return father[x] = getFather(father[x]); }
bool cmp(edge a, edge b){ //城墙排序为拆除消耗由大到小
return a.w > b.w;
}
LL kruskal(int n, int m, LL sum, int &cnt){ //kruskal算法
//由于需要改变cnt的值所以在这里cnt传引用
LL ans = sum; //传入的sum为拆除所有城墙所需的总消耗
for(int i = ; i <= n; i++){
father[i] = i; //初始化所有塔楼为不连通
}
sort(Edge + , Edge + + m, cmp); //城墙权值从大到小排序
for(int i = ; i <= m; i++){
int faNode1 = getFather(Edge[i].u);
int faNode2 = getFather(Edge[i].v);
if(faNode1 != faNode2){ //判断城墙连接的两个塔楼是否连通
father[faNode1] = faNode2; //不连通则标记为连通
ans -= Edge[i].w; //该城墙不需要拆数
}else{ //如果城墙两个端点塔楼已经连通则该城墙需要拆除
cnt++; //记录需要拆除的城墙数量
}
}
return ans; //返回的ans为拆除的最小消耗
}
int main(){
int n, m;
while(scanf("%d%d", &n, &m) != EOF){ //输入塔楼数n与城墙数m
for(int i = ; i <= n; i++){
int x, y;
scanf("%d%d", &x, &y); //吸收掉这些没用的坐标
}
LL sum = ;
for(int i = ; i <= m; i++){ //输入邻接表
scanf("%d%d%lld", &Edge[i].u, &Edge[i].v, &Edge[i].w);
sum += Edge[i].w; //记录总权值(拆除所有城墙的消耗)
}
int cnt = ; //cnt记录需要拆除的城墙
LL ans = kruskal(n, m, sum, cnt); //得到最小消耗
printf("%d %lld\n",cnt, ans);
}
return ;
}

HDU 6187 Destroy Walls的更多相关文章

  1. HDU 6187 Destroy Walls (思维,最大生成树)

    HDU 6187 Destroy Walls (思维,最大生成树) Destroy Walls *Time Limit: 8000/4000 MS (Java/Others) Memory Limit ...

  2. HDU 6187 Destroy Walls (对偶图最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6187 题意:有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一 ...

  3. HDU - 6187 (最大生成树) 最小生成树

    Destroy Walls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) ...

  4. hdu 4940 Destroy Transportation system(水过)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4940 Destroy Transportation system Time Limit: 2000/1 ...

  5. HDU 1692 Destroy the Well of Life 水题

    Destroy the Well of Life Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showprob ...

  6. hdu 4940 Destroy Transportation system (无源汇上下界可行流)

    Destroy Transportation system Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  7. HDU 4940 Destroy Transportation system(无源汇有上下界最大流)

    看不懂题解以及别人说的集合最多只有一个点..... 然后试了下题解的方法http://blog.sina.com.cn/s/blog_6bddecdc0102uzka.html 首先是无源汇有上下界最 ...

  8. 最短路(数据处理):HDU 5817 Ice Walls

    Have you ever played DOTA? If so, you may know the hero, Invoker. As one of the few intelligence car ...

  9. HDU 4940 Destroy Transportation system(无源汇上下界网络流)

    Problem Description Tom is a commander, his task is destroying his enemy’s transportation system. Le ...

随机推荐

  1. struts2+ckeditor配置图片上传

    又是一个漫漫长夜. 公司的编辑器坏了,用的是百度编辑器,上传图片的网址被框架给拦截了,我们本地怎么测试都没问题,放到服务器就这样了.和老李找了半天,疯了,没原因的. 笔者以前用过jsp+ckedito ...

  2. linux squid

    iptables -F iptables -F -t nat 网关 iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERAD ...

  3. XML--使用XML来将字符串分隔成行数据

    DECLARE @xml XML SET @xml=CAST(REPLACE('<ROOT><X>'+'AA,AB,AC,AD'+'</X></ROOT> ...

  4. “全栈2019”Java异常第十二章:catch与异常匹配

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  5. 【文文殿下】后缀自动机(Suffix Automaton,SAM)学习笔记

    前言 后缀自动机是一个强大的数据结构,能够解决很多字符串相关的(String-related)问题. 例如:他可以查询一个字符串在另一个字符串中出现的所有子串,以及查询一个字符串中本质不同的字符串的个 ...

  6. nginx实现动静分离--附nginx配置文件详解

    转自http://www.cnblogs.com/1214804270hacker/p/9299462.html 一.认识访问静态资源与访问动态资源的区别 静态资源:指存储在硬盘内的数据,固定的数据, ...

  7. 爬虫5:beautifulsoup

      灵活方便的网页解析库,处理高效,支持多种解析器,利用它不用编写正则表达式即可方便的实现网页信息的提取     一. BeautifulSoup的几种解析库   解析器 使用方法 优势 劣势 Pyt ...

  8. python有哪些比较隐藏的知识点?

    一.复用小整数以及小字符串 在Python语言中,设计者在优化Python语言时,为了提高Python的运行效率,所以就将一些小整数保存在系统表,没有释放回收(正常情况下,当Python中一个对象没有 ...

  9. C++基础知识-派生类、调用顺序、访问等级、函数遮蔽

    一.派生类的概念 类之间有一种层次关系,有父亲类,有孩子类. 车这个类,当成父类(也叫基类.超类),派生出卡车.轿车,他们属于孩子类(子类.派生类) 继承:有父亲类,有孩子类,构成了层次关系.继承这种 ...

  10. Java实现BF算法

    package 串的算法; public class BF { public static void main(String[] args) { String a = "aaabbaaacc ...