之前几天想着补些算法的知识,学了一下最小树形图的朱刘算法,不是特别理解,备了份模板以备不时之需,想不到多校冷不丁的出了个最小树形图,没看出来只能表示对算法不太理解吧,用模板写了一下,然后就过了。- -0

之前听到是最小树形图的时候觉得恍然大悟,非常裸,但是后来想想也不是特别裸,其实关键就是要想清楚要加回流的边,贴一份代码吧- -0

  1. #pragma warning(disable:4996)
  2. #include<cstdio>
  3. #include<set>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<stdlib.h>
  7. #include<vector>
  8. #include<map>
  9. #include<algorithm>
  10. #include<queue>
  11. #include<cmath>
  12. #include<functional>
  13. #include<string>
  14. using namespace std;
  15.  
  16. #define maxn 550
  17.  
  18. int n, m;
  19. int a[55];
  20.  
  21. struct Edge{
  22. int u, v, w;
  23. Edge(int ui, int vi, int wi) :u(ui), v(vi), w(wi){}
  24. Edge(){}
  25. };
  26.  
  27. vector<Edge> E;
  28. vector<int> vid[55];
  29.  
  30. int in[maxn]; // minimum pre edge weight
  31. int pre[maxn]; // pre vertex
  32. int vis[maxn]; // vis array
  33. int id[maxn]; // mark down the id
  34. int nv; // nv is the number of vertex after shrinking
  35.  
  36. int directed_mst(int root,int vertex_num)
  37. {
  38. int ret = 0; int nv = vertex_num;
  39. while (1){
  40. for (int i = 0; i < nv; ++i) in[i] = 1e9;
  41. for (int i = 0; i < E.size(); ++i){
  42. int u = E[i].u, v = E[i].v;
  43. if (E[i].w < in[v] && u != v){
  44. in[v] = E[i].w;
  45. pre[v] = u;
  46. }
  47. }
  48. for (int i = 0; i < nv; ++i){
  49. if (i == root) continue;
  50. if (in[i]>1e8) return -1;
  51. }
  52. int cnt = 0;
  53. memset(id, -1, sizeof(id));
  54. memset(vis, -1, sizeof(vis));
  55. in[root] = 0;
  56.  
  57. for (int i = 0; i < nv; ++i){
  58. ret += in[i];
  59. int v = i;
  60.  
  61. while (vis[v] != i&&id[v] == -1 && v != root){
  62. vis[v] = i;
  63. v = pre[v];
  64. }
  65. // v!=root means we find a circle,id[v]==-1 guarantee that it's not shrinked.
  66. if (v != root&&id[v] == -1){
  67. for (int u = pre[v]; u != v; u = pre[u]){
  68. id[u] = cnt;
  69. }
  70. id[v] = cnt++;
  71. }
  72. }
  73. if (cnt == 0) break;
  74. for (int i = 0; i < nv; ++i){
  75. if (id[i] == -1) id[i] = cnt++;
  76. }
  77. // change the cost of edge for each (u,v,w)->(u,v,w-in[v])
  78. for (int i = 0; i < E.size(); ++i){
  79. int v = E[i].v;
  80. E[i].u = id[E[i].u];
  81. E[i].v = id[E[i].v];
  82. if (E[i].u != E[i].v) E[i].w -= in[v];
  83. }
  84. // mark down the new root
  85. root = id[root];
  86. // mark down the new vertex number
  87. nv = cnt;
  88. }
  89. return ret;
  90. }
  91.  
  92. int main()
  93. {
  94. while (cin >> n >> m){
  95. if (n == 0 && m == 0) break;
  96. int tot = 0;
  97. for (int i = 1; i <= n; ++i) {
  98. vid[i].clear();
  99. scanf("%d", a + i);
  100. for (int j = 0; j <= a[i]; ++j){
  101. vid[i].push_back(++tot);
  102. }
  103. }
  104. ++tot;
  105. E.clear();
  106. for (int i = 1; i <= n; ++i){
  107. for (int j = 0; j < vid[i].size(); ++j){
  108. for (int k = j + 1; k < vid[i].size(); ++k){
  109. E.push_back(Edge(vid[i][k], vid[i][j], 0));
  110. }
  111. }
  112. }
  113. int ci, l1, di, l2, wi;
  114. for (int i = 0; i < m; ++i){
  115. scanf("%d%d%d%d%d", &ci, &l1, &di, &l2, &wi);
  116. E.push_back(Edge(vid[ci][l1], vid[di][l2], wi));
  117. }
  118. for (int i = 1; i <= n; ++i){
  119. E.push_back(Edge(0, vid[i][0], 0));
  120. }
  121. int ans = directed_mst(0,tot);
  122. printf("%d\n", ans);
  123. }
  124. return 0;
  125. }

HDU4966 GGS-DDU(最小树形图)的更多相关文章

  1. hdu4966 最小树形图+虚根

    /* 辛辛苦苦调试半天, 过了样例,竟然没有ac!! 网上对比了ac代码,感觉添加一个虚根就能ac 但是想不明白为什么 */ /* 第二天想了下,知道了为什么wa:因为从等级0连到其他课程等级i的不止 ...

  2. 最小树形图(hdu4966多校联赛9)

    GGS-DDU Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total ...

  3. hdu4966 最小树形图(最少辅导花费)

    题意:       以一些科目,和辅导班,每个科目最终要求修到某个等级,可以花一定的钱在辅导班把某一科目修到某一等级,进入辅导班的时候会有一个限制,那就是达到他给出的科目和等级限制,比如a b c d ...

  4. bzoj4349: 最小树形图

    最小树形图模板题…… 这种\(O(nm)\)的东西真的能考到么…… #include <bits/stdc++.h> #define N 60 #define INF 1000000000 ...

  5. hdu 4966 GGS-DDU (最小树形图)

    比较好的讲解:http://blog.csdn.net/wsniyufang/article/details/6747392 view code//首先为除根之外的每个点选定一条入边,这条入边一定要是 ...

  6. HDU 4966 GGS-DDU(最小树形图)

    n个技能,每个技能有0-a[i]的等级,m个课程,每个课程需要前置技能c[i]至少达到lv1[i]等级,效果是技能d[i]达到lv2[i]等级,花费w[i]. 输出最小花费使得全技能满级(初始全技能0 ...

  7. hdu3072 强连通+最小树形图

    题意:有一个人他要把一个消息通知到所有人,已知一些通知关系:A 能通知 B,需要花费 v,而又知道,如果某一个小团体,其中的成员相互都能直接或间接通知到,那么他们之间的消息传递是不需要花费的,现在问这 ...

  8. POJ3164 Command Network(最小树形图)

    图论填个小坑.以前就一直在想,无向图有最小生成树,那么有向图是不是也有最小生成树呢,想不到还真的有,叫做最小树形图,网上的介绍有很多,感觉下面这个博客介绍的靠谱点: http://www.cnblog ...

  9. HDU ACM 2121 Ice_cream’s world II (无根最小树形图)

    [解题思路]这题先看了NotOnlySuccess的解题思路,即设置虚根再处理的做法:弄了一个上午,再次有种赶脚的感觉~~如果需要找出为什么需要去比所有权值之和更大的数为新增的虚边的话,一开始我理解仅 ...

随机推荐

  1. SQLite数据库与Contentprovider(1)

    SQlite:类似mysql的数据库.把数据保存到.db文件夹中. Contentprovider:一般用于不同进程之间的数据共享(两个APP). 手动建库:http://www.runoob.com ...

  2. hdu 4217 Data Structure?/treap

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4217 可用线段树写,效率要高点. 这道题以前用c语言写的treap水过了.. 现在接触了c++重写一遍 ...

  3. Java之NIO传输数据

    NIO可谓陈词旧调,不值一提. 但之前都是泛泛而谈, 现在深入应用才知道秘诀所在. 对于SocketChannel有read()与write(),但由于"非阻塞IO"本质, 这二个 ...

  4. 关于如何将Excel数据导入到SQL Server中

    面对大量的Excel数据我们可能会非常苦恼,如果一条一条的插入到数据库:不仅会耗大量的时间,而且还可能会发生错误,现在我来说一下如何导入数据! 1.准备工作 首先要在Excel中建立数据表对应的数据字 ...

  5. Rstdio中更换R版本

    1.打开Rstdio,选择Tool --> Global Options.

  6. MYSQL 一些用法

    LOAD DATA LOCAL INFILE 'C:/xampp/htdocs/test/file/sample.csv' INTO TABLE sample1 FIELDS TERMINATED B ...

  7. 设计模式之Composite(组合)模式

    1.出现原因 1.在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即它们在充当对象的同时,又是其他对象的容器. 如何将“客户代码与复杂的对象容器结构”解耦(将这种组合容器对象设计成树形结构 ...

  8. 封装getByClass

    方法一:(普通版),获取单一的class: function getByClass(oParent, sClass) { var aResult = []; var aEle = oParent.ge ...

  9. jquery动态加载JS【方法getScript】的改进

    http://www.cnblogs.com/cuitsl/archive/2012/11/15/2771549.html

  10. jQuery 效果 - slideDown() 方法[菜单导航栏常用]

    实例 以滑动方式显示隐藏的 <p> 元素: $(".btn2").click(function(){ $("p").slideDown(); }); ...