题目链接http://acm.hdu.edu.cn/showproblem.php?pid=6349

题目

三原色图

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 555    Accepted Submission(s): 186

Problem Description
度度熊有一张 n

个点 m

条边的无向图,所有点按照 1,2,⋯,n

标号,每条边有一个正整数权值以及一种色光三原色红、绿、蓝之一的颜色。

现在度度熊想选出恰好 k

条边,满足只用这 k

条边之中的红色边和绿色边就能使 n

个点之间两两连通,或者只用这 k

条边之中的蓝色边和绿色边就能使 n

个点之间两两连通,这里两个点连通是指从一个点出发沿着边可以走到另一个点。

对于每个 k=1,2,⋯,m

,你都需要帮度度熊计算选出恰好 k

条满足条件的边的权值之和的最小值。

 
Input
第一行包含一个正整数 T

,表示有 T

组测试数据。

接下来依次描述 T

组测试数据。对于每组测试数据:

第一行包含两个整数 n

和 m

,表示图的点数和边数。

接下来 m

行,每行包含三个整数 a,b,w

和一个字符 c

,表示有一条连接点 a

与点 b

的权值为 w

、颜色为 c

的无向边。

保证 1≤T≤100

,1≤n,m≤100

,1≤a,b≤n

,1≤w≤1000

,c∈{R,G,B}

,这里 R,G,B

分别表示红色、绿色和蓝色。

 
Output
对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 x

组测试数据,接下来 m

行,每行包含一个整数,第 i

行的整数表示选出恰好 i

条满足条件的边的权值之和的最小值,如果不存在合法方案,输出 −1

,行末不要有多余空格。

 
Sample Input
1
5 8
1 5 1 R
2 1 2 R
5 4 5 R
4 5 3 G
1 3 3 G
4 3 5 G
5 4 1 B
1 2 2 B
 
Sample Output
Case #1:
-1
-1
-1
9
10
12
17
22
 
解题思路:采用克鲁斯卡尔算法,构建最小生成树,边数小于n-1,无法构成所以答案为-1,如果可以构成的话,必定需要花费了n-1条边,对于剩下的n~m条边,参考大佬博客的做法,我们可以把它们放到一个从小到大排列的优先队列里,这样我们只要每次讲队首元素加入到答案,则出队即可。只需要跑两次克鲁斯卡尔,取答案的最小值就可以了。
 
这里也挺需要特别注意无法构成最小生成树的情况,答案全部为-1,我开始就在这WA了。
 
附上代码:
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<queue>
  6. using namespace std;
  7. #define maxn 105
  8. #define inf 0x3f3f3f3f
  9. priority_queue<int,vector<int>,greater<int> >que;
  10. int n,m,par[maxn],rk[maxn],ans[maxn];
  11. struct node{
  12. int u,v,w,c;
  13. bool operator<(const node &a)const
  14. { //按边的权值从小到大排
  15. return w<a.w;
  16. }
  17. }edge[maxn]; //边数组
  18. void init()
  19. { //初始化
  20. for(int i=;i<=n;i++)
  21. {
  22. par[i]=i;
  23. rk[i]=;
  24. }
  25. }
  26. int find(int x)
  27. { //查找节点x所在树的根节点
  28. if(x==par[x])
  29. return x;
  30. else //路径压缩
  31. return par[x]=find(par[x]);
  32. }
  33. void unite(int x,int y)
  34. { //将两个不同集合的节点合并,两个集合变一个
  35. int fx=find(x),fy=find(y);
  36. if(rk[fx]<rk[fy])
  37. par[fx]=fy;
  38. else
  39. {
  40. par[fy]=fx;
  41. if(rk[fx]==rk[fy])
  42. rk[fx]++;
  43. }
  44. }
  45. void kruskal(int c)
  46. {
  47. int cnt=,sum=; //cnt已选边的数目,sum为当前边权值之和
  48. init();
  49. while(!que.empty())
  50. que.pop();
  51. for(int i=;i<m;i++)
  52. {
  53. int u=edge[i].u,v=edge[i].v,col=edge[i].c;
  54. if(find(u)!=find(v)&&col!=c&&cnt<=n-)
  55. {
  56. sum+=edge[i].w;
  57. cnt++;
  58. unite(u,v);
  59. if(cnt==n-)
  60. {
  61. if(ans[cnt]==-) ans[cnt]=sum;
  62. else ans[cnt]=min(ans[cnt],sum);
  63. }
  64. }
  65. else //将未选中的边加入优先队列
  66. que.push(edge[i].w);
  67. }
  68. if(cnt<n-) return;
  69. while(!que.empty())
  70. {
  71. sum+=que.top();
  72. que.pop();
  73. ++cnt;
  74. if(ans[cnt]==-) ans[cnt]=sum;
  75. else ans[cnt]=min(ans[cnt],sum);
  76. }
  77. }
  78. int main()
  79. {
  80. int T;
  81. scanf("%d",&T);
  82. int kase=;
  83. while(T--)
  84. {
  85. scanf("%d%d",&n,&m);
  86. char c;
  87. for(int i=;i<m;i++)
  88. {
  89. scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
  90. getchar();
  91. c=getchar();
  92. if(c=='B') edge[i].c=;
  93. else if(c=='R') edge[i].c=;
  94. else edge[i].c=;
  95. }
  96. memset(ans,-,sizeof(ans));
  97. sort(edge,edge+m);
  98. kruskal(); //第一种方案颜色不可为蓝色
  99. kruskal(); //第二种方案颜色不可为红色
  100. printf("Case #%d:\n",++kase);
  101. for(int i=;i<=m;i++)
  102. printf("%d\n",ans[i]);
  103. }
  104. }

2018"百度之星"程序设计大赛 - 资格赛hdu6349三原色(最小生成树)的更多相关文章

  1. 2018"百度之星"程序设计大赛 - 资格赛 - 题集

    1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答 ...

  2. 2018"百度之星"程序设计大赛 - 资格赛 A/B/E/F

    调查问卷  Accepts: 505  Submissions: 2436  Time Limit: 6500/6000 MS (Java/Others)  Memory Limit: 262144/ ...

  3. 2018"百度之星"程序设计大赛 - 资格赛 1002 子串查询

    题面又是万能的毒毒熊... 实在不想写了,就只写了这题 记26个前缀和查询枚举最小值直接算 实在是氵的死 而且我忘记输出Case #%d 想了很久 >_< #include<bits ...

  4. 子串查询(二维前缀数组) 2018"百度之星"程序设计大赛 - 资格赛

    子串查询 Time Limit: 3500/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  5. 2018"百度之星"程序设计大赛 - 资格赛

    调查问卷  Accepts: 1546  Submissions: 6596  Time Limit: 6500/6000 MS (Java/Others)  Memory Limit: 262144 ...

  6. HDU6383 2018 “百度之星”程序设计大赛 - 初赛(B) 1004-p1m2 (二分)

    原题地址 p1m2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  7. HDU6380 2018 “百度之星”程序设计大赛 - 初赛(B) A-degree (无环图=树)

    原题地址 degree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  8. hdu 6082 度度熊与邪恶大魔王(2017"百度之星"程序设计大赛 - 资格赛 )

    度度熊与邪恶大魔王 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. 2014年百度之星程序设计大赛 - 资格赛 第二题 Disk Schedule

    双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1和北京大学OJ2677都出现了这个题目. 旅行商问题描写叙述:平面上n个点,确定一条连接各点的最短闭合旅程 ...

随机推荐

  1. MySQL数据库性能优化思路与解决方法(二转)

    原文:http://bbs.landingbj.com/t-0-242512-1.html 1.锁定表 尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是 ...

  2. html5-attr和prop

    ###1.什么是attrbute和property attribute(attr) html标签的预定义属性 checked html标签的自定义属性         a eg: <input ...

  3. mybatis出现NoSuchMethodException异常

    今天在idea中调试项目(ssm搭建的项目)的时候,mybatis突然出现了NoSuchMethodException异常,具体的异常时: java.lang.NoSuchMethodExceptio ...

  4. 【gedit】 显示行号

    打开gedit文本编辑器->Edit(编辑)->preferences(预设)->view(视图)->在Display line numbers前打勾->close

  5. JDK 环境变量的设置、eclipse、Tomcat的配置

    一.JDK的环境变量的设置 环境变量设置: JDK下载好后,(1)选择电脑属性-高级系统设置-高级-环境变量,接着在系统变量中(2)新建JAVA_HOME,变量值设置为下载好后JDK在电脑中的路径;( ...

  6. 堆排序的Python实现

    参考: https://www.jianshu.com/p/d174f1862601

  7. python爬虫之初始Selenium

    1.初始 Selenium[1]  是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Moz ...

  8. 移动端Web界面滚动touch事件

    解决办法一: elem.addEventListener( 'touchstart', fn, { passive: false } ); 解决办法二: * { touch-action: pan-y ...

  9. UDP反射DDoS攻击原理和防范

    东南大学:UDP反射DDoS攻击原理和防范 2015-04-17 中国教育网络 李刚 丁伟 反射攻击的防范措施 上述协议安装后由于有关服务默认处于开启状态,是其被利用的一个重要因素.因此,防范可以从配 ...

  10. adoquery.refresh和adoquery.query的区别

    大的区别没有 1: requery是通过重新发出原始命令并再次检索数据,可使用 Requery 方法刷新来自数据源的 Recordset 对象的全部内容.调用该方法等于相继调用 Close 和 Ope ...