题目描述:

有n个小岛,其中有的小岛之间没有通路,要修这样一条通路需要花费一定的钱,还有一些小岛之间是有通路的。现在想把所有的岛都连通起来,求最少的花费是多少。

输入:

第一行输入T,代表多少组数据。

第二行输入三个整数n , m , k,分别代表一共有n个小岛,m条路径可供选择,k表示有连通岛的个数。

接下来的m行,每行三个整数p , q , c ,代表建设p到q的通路需要花费的钱为c。

接下的k行,每一行的数据输入如下:先输入Q,代表这个连通分量里面有Q个小岛,然后输入Q个小岛,代表这Q个小岛是连通的。

输出:

输出最少花费为多少,如果无法修建出此路,输出"-1"。


其实这道题属于并查集的入门题目,解法如下:

先用并查集把还在连通的k个分量给合并起来,此时记录好连通分量的个数。然后把Q条路径排一遍序,然后从最小的路径开始枚举,对每一条路径判断起点和终点是否在同一个连通分量内,如果不在的话将这两点合并,连通分量的个数减一,加上修建这条路的花费,如此枚举,知道连通分量的个数为1。如果最后的连通分量大于1,则说明无法连接,输出-1。

可能是解法不太好吧,最后890ms险过,这几天做的并查集都是险过QAQ...

  1. #include <iostream>
  2. #include <iomanip>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <algorithm>
  6. #include <functional>
  7. #include <vector>
  8. #include <cmath>
  9. #include <string>
  10. #include <stack>
  11. #include <queue>
  12. using namespace std;
  13. int k , n , m , father[];
  14. struct P{
  15. int start , end , cost;
  16. }p[+]; //路径
  17. bool cmp(P a , P b)
  18. {
  19. return b.cost > a.cost;
  20. }
  21. void init()
  22. {
  23. for(int i = ; i <= n ; i++) {
  24. father[i] = i;
  25. }
  26. }
  27. int getf(int v)
  28. {
  29. return father[v] = (v == father[v]) ? v : getf(father[v]);
  30. }
  31. void merge(int x , int y)
  32. {
  33. int a , b;
  34. a = getf(x);
  35. b = getf(y);
  36. if(a != b)
  37. father[b] = a;
  38. }
  39. int main()
  40. {
  41. int T , i , j;
  42. scanf("%d",&T);
  43. while(T--)
  44. {
  45. scanf("%d %d %d",&n,&m,&k);
  46. for(i = ; i <= m ; i++)
  47. scanf("%d %d %d",&p[i].start,&p[i].end,&p[i].cost);
  48. init();
  49. for(i = ; i <= k ; i++) {
  50. int cnt;
  51. scanf("%d",&cnt);
  52. int *tmp = new int[cnt];
  53. for(j = ; j < cnt ; j++) {
  54. scanf("%d",&tmp[j]);
  55. if(j != )
  56. merge(tmp[j-] , tmp[j]);
  57. }
  58. delete []tmp;
  59. }
  60. sort(p+ , p+m+ , cmp);
  61. int sum = ; //连通分量的个数
  62. int ans = ;
  63. for(i = ; i <= n ; i++)
  64. if(father[i] == i)
  65. sum++;
  66. for(i = ; i <= m ; i++) {
  67. if(sum == ) //连通分量的个数为1时,说明这时候已经完成
  68. break;
  69. if(getf(p[i].start) != getf(p[i].end)) {
  70. merge(p[i].start , p[i].end);
  71. ans += p[i].cost;
  72. sum--; //连上一条路后连通分量-1
  73. }
  74. }
  75. if(sum > ) {
  76. printf("-1\n");
  77. } else {
  78. printf("%d\n",ans);
  79. }
  80. }
  81. return ;
  82. }

HDU3371 Connect the Cities的更多相关文章

  1. hdu3371 Connect the Cities (MST)

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. Connect the Cities[HDU3371]

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...

  3. Connect the Cities(hdu3371)并查集(附测试数据)

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  4. Connect the Cities(MST prim)

    Connect the Cities Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

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

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

  6. hdu 3371 Connect the Cities

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3371 Connect the Cities Description In 2100, since th ...

  7. hdoj 3371 Connect the Cities

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  8. Connect the Cities(prime)

    Connect the Cities Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  9. Connect the Cities(prim)用prim都可能超时,交了20几发卡时过的

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. c#入门学习-Action和Func的使用

    我的理解就是:Action和Func就是官方声明好的代理using System; namespace funcActionDemo{    class MainClass    {        p ...

  2. 转:基础篇|PHP如何解决网站大流量和高并发

    基础篇 高并发架构基础概念和优化思路 高并发架构相关概念 并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程 ...

  3. 洛谷P3147 [USACO16OPEN]262144

    P3147 [USACO16OPEN]262144 题目描述 Bessie likes downloading games to play on her cell phone, even though ...

  4. CF986A Fair

    题目描述 Some company is going to hold a fair in Byteland. There are n n n towns in Byteland and m m m t ...

  5. 洛谷P4018 Roy&October之取石子

    题目背景 \(Roy\)和\(October\)两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有\(n\)个石子,两人每次都只能取\(p^k\)个(\(p\)为质数,\(k\)为自然数,且 ...

  6. sql数据库发布、订阅同步方式操作

    Sql数据库发布订阅分为两个步骤:1.发布.2.订阅.首先在数据源数据库服务器上对需要同步的数据进行发布,然后在目标数据库服务器上对上述发布进行订阅. 一.发布. 发布需要用实际的服务器名称,不能使用 ...

  7. 029 Divide Two Integers 两数相除

    不使用乘号,除号和取模符号将两数相除.如果溢出返回 MAX_INT.详见:https://leetcode.com/problems/divide-two-integers/description/ ...

  8. C++之struct

    C++的struct对C做和很多补充,里面可以放函数(构造函数和虚函数),也可以同struct和class的继承,在C++中也完全可以替代class.他们之间的主要区别: 1 calss默认是私有继承 ...

  9. c#文件相关笔记

    1.将*.txt文件内容转换为一个字符串str FileStream fs = new FileStream("路径\\*.txt", FileMode.Open); Stream ...

  10. Kotlin基础知识

    1. 改进点/基础 //安全判空 val length = text?.length; //类型转换 if (object is Car) { var car = object as Ca } //操 ...