Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16070    Accepted Submission(s): 4177

Problem Description
In 2100, since the sea level rise, most of the cities disappear.
Though some survived cities are still connected with others, but most of
them become disconnected. The government wants to build some roads to
connect all of these cities again, but they don’t want to take too much
money.  
 
Input
The first line contains the number of test cases.
Each
test case starts with three integers: n, m and k. n (3 <= n
<=500) stands for the number of survived cities, m (0 <= m <=
25000) stands for the number of roads you can choose to connect the
cities and k (0 <= k <= 100) stands for the number of still
connected cities.
To make it easy, the cities are signed from 1 to n.
Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
Then
follow k lines, each line starts with an integer t (2 <= t <= n)
stands for the number of this connected cities. Then t integers follow
stands for the id of these cities.
 
Output
For each case, output the least money you need to take, if it’s impossible, just output -1.
 
Sample Input
1
6 4 3
1 4 2
2 6 1
2 3 5
3 4 33
2 1 2
2 1 3
3 4 5 6
 
Sample Output
1
 
题意:有n个城市,可以修其中的m条道路,然后还有k行,每一行有t个城市,这t个城市都已经连通。
题解:开始以为是普通的并查集,结果死活TLE,用了启发式合并才AC。而且就像很多人的题解里面说的用C++ AC不了。
启发式合并:启发式合并是为了解决合并过程中树退化成链的情况,用dep[i]表示根为i的树的最大深度,合并ra和rb时,采用最大深度小的向最大深度大的进行合 并,如果两棵树的最大深度一样,则随便选择一个作为根,并且将根的最大深度dep自增1,这样做的好处是在n次操作后,任何一棵集合树的最大深度都不会超过log(n),所以使得查找的复杂度降为O( log(n) )。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int N = ;
const int M = ;
struct Edge
{
int s,e,len;
} edge[M];
int father[N],n,m,k;
int dep[N];
int _find(int x)
{
if(x==father[x])return x;
return _find(father[x]);
}
int cmp(Edge a,Edge b)
{
return a.len<b.len;
}
int kruskal(int m)
{
sort(edge+,edge+m+,cmp);
int cost = ;
for(int i=; i<=m; i++)
{
int x = _find(edge[i].s);
int y = _find(edge[i].e);
if(x!=y)
{
if(dep[x]==dep[y])
{
father[x] = y;
dep[y]++;
}
else if(dep[x]<dep[y])
{
father[x] = y;
}
else
{
father[y]=x;
}
cost += edge[i].len;
}
}
return cost;
}
int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=; i<=n; i++)
{
father[i] = i;
dep[i] =;
}
for(int i=; i<=m; i++)
{
scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].len);
}
while(k--)
{
int t,a;
scanf("%d%d",&t,&a);
t--;
while(t--)
{
int b;
scanf("%d",&b);
int x = _find(a);
int y = _find(b);
if(x!=y)
{
if(dep[x]==dep[y])
{
father[x] = y;
dep[y]++;
}
else if(dep[x]<dep[y])
{
father[x] = y;
}
else
{
father[y]=x;
}
}
}
}
int ans = ;
int cost = kruskal(m);
for(int i=; i<=n; i++)
{
if(father[i]==i) ans++;
}
if(ans==)printf("%d\n",cost);
else printf("-1\n");
}
}
 

hdu 3371(启发式合并的最小生成树)的更多相关文章

  1. hdu 3371 Connect the Cities(最小生成树)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3371 984ms风险飘过~~~ /************************************ ...

  2. hdu 3371 Connect the Cities (最小生成树Prim)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3371 题目不难 稍微注意一下 要把已经建好的城市之间的花费定义为0,在用普通Prim算法就可以了:我没 ...

  3. HDU 3371 Connect the Cities 最小生成树(和关于sort和qsort的一些小发现)

    解题报告:有n个点,然后有m条可以添加的边,然后有一个k输入,表示一开始已经有k个集合的点,每个集合的点表示现在已经是连通的了. 还是用并查集加克鲁斯卡尔.只是在输入已经连通的集合的时候,通过并查集将 ...

  4. HDU - 6133 启发式合并

    题意:给出一棵树共\(n\)个顶点,每个顶点有一个权值\(val_i\),你需要对每个节点统计一个最优解 每个节点的解按照一定规则产生:取出该节点的子树下所有的顶点,把顶点任意排序成一个序列,设为\( ...

  5. HDU 3371 kruscal/prim求最小生成树 Connect the Cities 大坑大坑

    这个时间短 700多s #include<stdio.h> #include<string.h> #include<iostream> #include<al ...

  6. HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up beca ...

  7. [HDU 3712] Fiolki (带边权并查集+启发式合并)

    [HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...

  8. 数据结构(trie,启发式合并):HDU 5841 Alice and Bob

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABJEAAAE6CAIAAAApz1RvAAAgAElEQVR4nO3d3css1b3g8fyTdbHJbD

  9. hdu 6133---Army Formations(启发式合并+树状数组)

    题目链接 Problem Description > Stormtroopers were the assault/policing troops of the Galactic Empire. ...

随机推荐

  1. 《数据结构与算法分析:C语言描述》复习——第七章“哈希”——哈希表

    2014.06.22 12:36 简介: 哈希是一种数学思想,将不定长数据通过函数转换为定长数据.不定长数据通常意味着碎片化,动态分配内存等等影响存储和性能的因素.当这个定长数据是一个无符号整数时,可 ...

  2. 《Cracking the Coding Interview》——第13章:C和C++——题目5

    2014-04-25 19:59 题目:C的关键字volatile有什么用? 解法:搞硬件设计的人好像更关注这个关键字.volatile本身是易变的意思,应该和persistent有反义词关系吧.说一 ...

  3. SQL Server 分组取 Top 笔记(row_number + over 实现)

    先看SQL语句(注意:这是在SQL Server 2005+ [包括2005] 的版本才支持的哦,o(∩_∩)o 哈哈~) SELECT col1,col2,col3 FROM table1 AS a ...

  4. WIN10把照片查看器设为默认看图软件

    WIN10默认是PHOTO,没有以前WIN7的照片查看器好用,要改回来的方法如下:   在注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Photo ...

  5. MySQL、MongoDB、Redis 数据库之间的区别与使用(本章迭代更新)

    MySQL.MongoDB.Redis 数据库之间的区别与使用 MySQL.MongoDB.Redis 数据库之间的区别与使用(本章迭代更新) update:2019年2月20日 15:21:19(本 ...

  6. 解决Navicat for MySQL 连接 Mysql 8.0.11 出现1251- Client does not support authentication protocol 错误

    安装MySQL8.0之后,使用Navicat连接数据库,报1251错误. 上网搜索解决方案,网上说出现这种情况的原因是:mysql8 之前的版本中加密规则是mysql_native_password, ...

  7. ironic baremetal rescue process

    1.用户调用Nova的rescue函数 nova/virt/ironic/driver.py class IronicDriver(virt_driver.ComputeDriver): ...... ...

  8. heat应用

    作为OpenStack中的编排引擎,Heat能够出色的完成编排任务,井井有条地管理编排出来的资源.但同时,Heat也是一个出色的应用部署引擎,它提供了一套内置的框架去完成一系列复杂的应用部署任务. 使 ...

  9. 关于 vee-validate直接引用的方法

    转载于:https://blog.csdn.net/hy111/article/details/79046500?%3E 由于当前项目使用的是基于jQuery的前端结构,尝试在新增需求中使用VUE2, ...

  10. 电信学院第一届新生程序设计竞赛题解及std

    首先非常感谢各位同学的参加,还有出题验题同学的辛勤付出 昨天想偷懒就是不想再把我C++11的style改没了,大家看不懂的可以百度一下哦,懒得再写gcc了,毕竟代码是通的 //代表的是行注释,所以那个 ...