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 = 1; i <= n; i++){father[i] = i;  //初始化所有塔楼为不连通
    }sort(Edge + 1, Edge + 1 + m, cmp);  //城墙权值从大到小排序for(int i = 1; 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;elsereturn father[x] = getFather(father[x]);}

并查集

AC代码

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn = 2e5+100;
 8 struct edge{    //edge储存城墙
 9     int u, v;   //城墙连接的两个结点
10     LL w;   //拆除的消耗
11 }Edge[maxn];
12 int father[maxn];
13 int getFather(int x)    //并查集部分
14 {
15     if(father[x] == x)
16         return x;
17     else
18         return father[x] = getFather(father[x]);
19
20 }
21 bool cmp(edge a, edge b){   //城墙排序为拆除消耗由大到小
22     return a.w > b.w;
23 }
24 LL kruskal(int n, int m, LL sum, int &cnt){ //kruskal算法
25     //由于需要改变cnt的值所以在这里cnt传引用
26     LL ans = sum;   //传入的sum为拆除所有城墙所需的总消耗
27     for(int i = 1; i <= n; i++){
28         father[i] = i;  //初始化所有塔楼为不连通
29     }
30     sort(Edge + 1, Edge + 1 + m, cmp);  //城墙权值从大到小排序
31     for(int i = 1; i <= m; i++){
32         int faNode1 = getFather(Edge[i].u);
33         int faNode2 = getFather(Edge[i].v);
34         if(faNode1 != faNode2){ //判断城墙连接的两个塔楼是否连通
35             father[faNode1] = faNode2;  //不连通则标记为连通
36             ans -= Edge[i].w;   //该城墙不需要拆数
37         }else{  //如果城墙两个端点塔楼已经连通则该城墙需要拆除
38             cnt++;  //记录需要拆除的城墙数量
39         }
40     }
41     return ans; //返回的ans为拆除的最小消耗
42 }
43 int main(){
44     int n, m;
45     while(scanf("%d%d", &n, &m) != EOF){    //输入塔楼数n与城墙数m
46         for(int i = 1; i <= n; i++){
47             int x, y;
48             scanf("%d%d", &x, &y);  //吸收掉这些没用的坐标
49         }
50         LL sum = 0;
51         for(int i = 1; i <= m; i++){    //输入邻接表
52             scanf("%d%d%lld", &Edge[i].u, &Edge[i].v, &Edge[i].w);
53             sum += Edge[i].w;   //记录总权值(拆除所有城墙的消耗)
54         }
55         int cnt = 0;    //cnt记录需要拆除的城墙
56         LL ans = kruskal(n, m, sum, cnt);   //得到最小消耗
57         printf("%d %lld\n",cnt, ans);
58     }
59 return 0;
60 }

转载于:https://www.cnblogs.com/suvvm/p/9961183.html

HDU 6187 Destroy Walls相关推荐

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

    题干: Long times ago, there are beautiful historic walls in the city. These walls divide the city into ...

  2. I - Destroy Walls (HDU - 6187)

    - 题目大意 有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一个区域,问最小花费. - 解题思路 先开始想不通,看了别人突然恍然大悟,根据欧拉公式我们可以知道 ...

  3. Destroy Walls

    点击打开链接 Problem Description Long times ago, there are beautiful historic walls in the city. These wal ...

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

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

  5. 2019.9.19最小生成树知识点总结

    ​​​​​HDU 1102 Constructing Roads(最小生成树-Prim) 最常见的,将已建成的路的权值设置为0,求最小生成树! HDU 1162 Eddy's picture(最小生成 ...

  6. 2017ACM/ICPC广西邀请赛

    2017ACM/ICPC广西邀请赛(感谢广西大学) 题号 题目 考点 难度 A A Math Problem 数论 签到题 B Color it C Counting Stars D Covering ...

  7. 基础省选+NOI 第9部分 网络流

    1.二分图匹配 算法竞赛入门经典训练指南+陈锋+ch5.5_二分图的匹配 算法竞赛入门经典训练指南+陈锋+ch5.5_二分图的匹配_哔哩哔哩_bilibili SWPU-ACM每周算法讲堂-匈牙利算法 ...

  8. 省选+NOI 第四部分 图论

    二分图匹配 算法竞赛入门经典训练指南+陈锋+ch5.5_二分图的匹配 算法竞赛入门经典训练指南+陈锋+ch5.5_二分图的匹配_哔哩哔哩_bilibili SWPU-ACM每周算法讲堂-匈牙利算法 S ...

  9. NOI图论算法:网络流

    网络流 https://www.bilibili.com/video/BV15p4y1C7zW https://www.bilibili.com/video/BV1HE411Y7sM https:// ...

最新文章

  1. JSTL标签库学习笔记
  2. 电子信息工程考研专业c语言,电子信息工程考研方向
  3. 【opencv】(1) 基础操作:图像视频读取、图像截取、颜色通道
  4. Ubuntu 11.10 开机让 Varnish 跟随 Nginx 一起启动
  5. 多因素方差分析_方差分析入门
  6. mysql保存中文乱码的原因和解决办法
  7. Linux命令之telnet 命令
  8. 安装 sql server 2005 com+ 目录要求警告 解决方案
  9. XML 语法速查笔记
  10. 太神奇!2张关键帧,AI生成完整运动过程!
  11. 7000块招不了一个工人
  12. CentOS 7防火墙开启路由功能和开放特定端口
  13. qt禁止拖动_Qt如何实现拖拽功能?
  14. Erlang中的RSA签名
  15. 【Kotlin -- 知识点】学习资料
  16. YUV格式讲解并使用ffmpeg生产YUV文件
  17. 11210怎么等于24_巧算24点
  18. Win10-64位上编译CodeLite13.0.0源码
  19. gem意思_GEM邓紫棋的GEM是什么意思
  20. python3基础教程雪峰_[雪峰磁针石博客]python3快速入门教程9重要的标准库

热门文章

  1. 祖传Python代码
  2. 985计算机专业考研难度排名,全国100所大学考研难易排名,985反而更好考,有意思...
  3. DiscoNet:基于Distilled Collaboration Graph的V2V协同感知
  4. vc messagebox怎么选择选项_亚马逊VC卖家被迫转向第三方卖家,下一步要怎么做?...
  5. Python基础学习第三天——条件控制与while循环语句
  6. kudiffy-一个很酷的自动化回归平台
  7. “C9、国防七子、两电一邮、两财一贸”...,你知道几个大学的称号?
  8. 合泰杯——合泰单片机工程之点亮LED
  9. Praat脚本-014 | 删除选择区域内的所有边界条
  10. 57步进电机驱动板,可以通过编码器调速,支持SPI通讯屏显示,485通讯