http://acm.hdu.edu.cn/showproblem.php?pid=6141

题意:

求最大树形图。

思路:

把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决。

有个问题就是n结点的父亲结点的编号要尽量小,这里有个技巧可以用,权值编码,将所有边的权值都放大1000倍,对于和n相连的边,每条边在减去(n-u)的权值。这样就会去优先考虑编号小的边,而且因为权值最大为100,所以扩大1000是不会影响结果的。

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<sstream>
  6. #include<vector>
  7. #include<stack>
  8. #include<queue>
  9. #include<cmath>
  10. #include<map>
  11. #include<set>
  12. using namespace std;
  13. typedef long long ll;
  14. typedef pair<int,ll> pll;
  15. const int inf = 0x3f3f3f3f;
  16. const int maxn=+;
  17. const int mod=1e9+;
  18.  
  19. int n, m;
  20.  
  21. struct node
  22. {
  23. int u,v,w;
  24. }edge[*maxn];
  25.  
  26. int pre[maxn],id[maxn],use[maxn];
  27. int in[maxn];
  28.  
  29. int mini_tree(int root,int n,int m)//分别是树根,节点数,边数,序号从1开始
  30. {
  31. int ans=;
  32. int u;
  33. while(true)
  34. {
  35. for(int i=;i<=n;i++) in[i]=inf;
  36. for(int i=;i<=m;i++)
  37. {
  38. int u=edge[i].u;
  39. int v=edge[i].v;
  40. if(edge[i].w<in[v]&&u!=v)
  41. {
  42. in[v]=edge[i].w;
  43. pre[v]=u;
  44. }
  45. }//找最小的入边
  46. for(int i=;i<=n;i++)
  47. {
  48. if(i==root)continue;
  49. ans+=in[i];//把边权加起来
  50. if(in[i]==inf)//如果存在没有入弧的点则不存在最小树形图
  51. return -;
  52. }
  53. memset(id,-,sizeof(id));
  54. memset(use,-,sizeof(use));
  55. int cnt=;
  56. for(int i=;i<=n;i++)//枚举每个点,搜索找环
  57. {
  58. int v=i;
  59. while(v!=root&&use[v]!=i&&id[v]==-)
  60. {
  61. use[v]=i;
  62. v=pre[v];
  63. }
  64. if(v!=root&&id[v]==-)//当找到环的时候缩点编号
  65. {
  66. ++cnt;
  67. id[v]=cnt;
  68. for(u=pre[v];u!=v;u=pre[u])
  69. id[u]=cnt;
  70. }
  71. }
  72. if(cnt==)//如果没有环结束程序
  73. break;
  74. for(int i=;i<=n;i++)//把余下的不在环里的点编号
  75. if(id[i]==-)
  76. id[i]=++cnt;
  77. for(int i=;i<=m;i++)//建立新的图
  78. {
  79. int u=edge[i].u;
  80. int v=edge[i].v;
  81. edge[i].u=id[u];
  82. edge[i].v=id[v];
  83. if(edge[i].u!=edge[i].v)
  84. edge[i].w-=in[v];
  85. }
  86. n=cnt;//更新节点数和根节点的编号
  87. root=id[root];
  88. }
  89. return ans;
  90. }
  91.  
  92. int main()
  93. {
  94. //freopen("in.txt","r",stdin);
  95. int T;
  96. scanf("%d",&T);
  97. while(T--)
  98. {
  99. scanf("%d%d",&n,&m);
  100. for(int i=;i<=m;i++)
  101. {
  102. int u,v,w;
  103. scanf("%d%d%d",&u,&v,&w);
  104. w*=-;
  105. if(v==n) w-=(n-u);
  106. edge[i].u=u, edge[i].v=v, edge[i].w=w;
  107. }
  108. int ans=mini_tree(,n,m);
  109. printf("%d %d\n",-ans/,n-(-ans)%);
  110. }
  111. return ;
  112. }

HDU 6141 I am your Father!(最小树形图+权值编码)的更多相关文章

  1. HDU 6141 - I am your Father! | 2017 Multi-University Training Contest 8

    思路来自 FXXL 最小树形图模板用kuangbin的 /* HDU 6141 - I am your Father! [ 最小树形图 ] | 2017 Multi-University Traini ...

  2. The Minimum Cycle Mean in a Digraph 《有向图中的最小平均权值回路》 Karp

    文件链接 Karp在1977年的论文,讲述了一种\(O(nm)\)的算法,用来求有向强连通图中最小平均权值回路(具体问题请参照这里) 本人翻译(有删改): 首先任取一个节点 \(s\) ,定义 \(F ...

  3. HDU 6141 I am your Father!(最小树形图)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6141 [题目大意] 给出一个有向图,求1点为根的最小树形图使得第n个点的直接父亲编号最小 [题解] ...

  4. hdu 6141 I am your Father!

    题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6141 (2017 Multi-University Training Contest - Team ...

  5. HDU 2121 Ice_cream’s world II 最小树形图 模板

    开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

  6. HDU 2121 Ice_cream’s world II 最小树形图

    这个题就是需要求整个有向带权图的最小树形图,没有指定根,那就需要加一个虚根 这个虚根到每个点的权值是总权值+1,然后就可以求了,如果求出来的权值大于等于二倍的总权值,就无解 有解的情况,还需要输出最根 ...

  7. hdu 3072 有向图缩点成最小树形图计算最小权

    题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...

  8. hdu 1565&hdu 1569(网络流--最小点权值覆盖)

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  9. hdu 1875 给出每个结点的坐标 权值为两点间的距离 (MST)

    Sample Input2210 10 //坐标20 2031 12 21000 1000 Sample Output1414.2   //最小权值和*100  保留1位小数oh!       //不 ...

随机推荐

  1. Ubuntu16.04 安装 “宋体,微软雅黑,Consolas雅黑混合版编程字体” 等 Windows 7 下的字体

    Windows平台下,“宋体”.“微软雅黑”.“Courier New(编程字体)”用的比较多,看的也习惯了.那如何在 Ubuntu下也安装这些字体呢? 操作步骤如下: 第一步:从 Windows 7 ...

  2. gerrit 使用教程(一)

    原文地址:https://www.jianshu.com/p/b77fd16894b6 1, Gerrit是什么? Gerrit实际上一个Git服务器,它为在其服务器上托管的Git仓库提供一系列权限控 ...

  3. mysql中char和varchar详解

    一.首先创建表. CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `a` char(255) DEFAULT NULL) ENGINE=InnoDB DE ...

  4. 集合框架—常用的map集合

    1.Collections.synchronizedMap() 实现上在调用map所有方法时,都对整个map进行同步,而ConcurrentHashMap的实现却更加精细,它对map中的所有桶加了锁. ...

  5. SV中的Interface和Program

    Interface:SV中新定义的接口方式,用来简化接口连接,使用时注意在module或program之外定义interface,然后通过'include来添加进工程. interface  arb_ ...

  6. SQL Server报“GUID应包含带4个短划线的32位数”

    转自:http://www.seayee.net/article/info_106.html 最近在配置一台服务器的MS SQL Server 2005的维护计划自动备份数据库,能创建维护计划,但设置 ...

  7. SSRS创建复合型图表

    SSRS创建复合型图表 1.添加报表数据对应代码: if object_id('tb') is not null drop table tb; go CREATE TABLE tb(yearid in ...

  8. MIPSsim使用说明

    MIPSsim下载:https://files.cnblogs.com/files/jiangxinnju/MIPSsim.zip 启动模拟器 双击MIPSsim.exe,即可启动该模拟器.MIPSs ...

  9. web前端----JavaScript(JS)简单介绍

    JavaScript(JS) 一.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEa ...

  10. mysql 触发器 trigger用法 four

    实验4 触发器 (1)实验目的 掌握数据库触发器的设计和使用方法 (2)实验内容和要求 定义BEFORE触发器和AFTER触发器.能够理解不同类型触发器的作用和执行原理,验证触发器的有效性. (3)实 ...