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. [bzoj2932][POI1999]树的染色问题

    被百度搜到的题解(论文?)坑了. 写的那玩意好像石乐志... Description 一棵二叉树采用以下规则描述: 1.如果一个节点度数为0,则仅用一个元素“0”来描述它. 2.如果一个节点度数为1, ...

  2. Installation error: INSTALL_FAILED_CANCELLED_BY_USER

    我的手机本来是支持Androidstadio 调试手机的,我手机小米的,后来,系统升级了,我也没在意,第二天上班,已运行就报错: Installation error: INSTALL_FAILED_ ...

  3. JavaScript获取时间

    var myDate = new Date();            console.log(myDate.getFullYear()); //获取完整的年份(4位,1970-????)       ...

  4. 《Cracking the Coding Interview》——第7章:数学和概率论——题目5

    2014-03-20 02:20 题目:给定二维平面上两个正方形,用一条直线将俩方块划分成面积相等的两部分. 解法:穿过对称中心的线会将面积等分,所以连接两个中心即可.如果两个中心恰好重合,那么任意穿 ...

  5. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)【转】

    原文链接:https://www.cnblogs.com/gdsblog/p/8465401.html 相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transi ...

  6. neutron floating ip 限速

    查看浮动ip的id [root@10e131e69e14 oz]# openstack floating ip show 36.111.0.197 +---------------------+--- ...

  7. 【视觉SLAM14讲】ch4心得与课后题答案【仅供参考】

    答案: Q1:验证SO(3) SE(3) Sim(3)关于乘法成群 SO(3) : 由P64最开始可知,乘法代表了旋转,而SO(3)是旋转矩阵的集合, SE(3)  Sim(3)  同理(最基础的部分 ...

  8. Set(), Get() 真正的目的

    在各种面向对象编程中,都有 Set(), Get() 两种方法. 1 常见理解 1 为了保证安全性 2 为了规范代码 其实这些理解都是对的.具体看我们从哪个角度去理解这个内容. 2 个人理解 2.1 ...

  9. php session访问限制

    登录 <?php // 启动会话 session_start(); // 注册登陆成功的 admin 变量,并赋值 true $_SESSION["admin"] = tru ...

  10. ocrosoft Contest1316 - 信奥编程之路~~~~~第三关 问题 P: 【数组】1234方阵(phalanx)

    http://acm.ocrosoft.com/problem.php?cid=1316&pid=15 题目描述 编程打印如下规律的n*n方阵.输入n,按规律输出方阵. 方阵规律如下图:使左对 ...