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

  (2017 Multi-University Training Contest - Team 8 - 1009)

解 

  首先这是一个有向图,所以使用最小树形图算法。

  然后题目要求的是节点n的父亲节点的值最小,

  那么,可以把全部边的值乘以1000,如果这条边的终止点是节点n的话,设这条边的起始点为u,那么边值加上(999-u),这样就能保证优先取字典序小的,

  然后由于题目要求的是最大的,所以可以把边的值取倒数。

  

  至于最小树形图算法,

  1. 找当前图每个节点的非自环最小入边,

  2. 如果当天图存在环:把环缩成点,然后构造一张新图,返回步骤1,(至于如何构造,见下图)

   否则结束  

  这张图我复制的(我感觉这张图超好懂来着),来源:O∧O (貌似来源处这张图也是复制的)

  

  (思路来自题解)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define MAXN 1005
  5. #define INF 0x7f7f7f7f
  6. using namespace std;
  7. typedef long long ll;
  8. struct node
  9. {
  10. int u, v;
  11. ll w;
  12. }edge[MAXN * MAXN];
  13. int pre[MAXN], id[MAXN], vis[MAXN], n, m, pos;
  14. int ans_father;
  15. ll in[MAXN];
  16. ll Directed_MST(int root, int V, int E) //边、点全是从0开始计算的
  17. {
  18. ll ret = 0;//存最小树形图总权值
  19. while(true)
  20. {
  21. int i;
  22. //1.找每个节点的最小入边
  23. for( i = 0; i < V; i++)
  24. in[i] = INF;//初始化为无穷大
  25. for( i = 0; i < E; i++)//遍历每条边
  26. {
  27. int u = edge[i].u;
  28. int v = edge[i].v;
  29. if(edge[i].w < in[v] && u != v)//说明顶点v有条权值较小的入边 记录之
  30. {
  31. pre[v] = u;//节点u指向v
  32. in[v] = edge[i].w;//最小入边
  33. if(u == root)//这个点就是实际的起点
  34. pos = i;
  35. }
  36. }
  37. for( i = 0; i < V; i++)//判断是否存在最小树形图
  38. {
  39. if(i == root)
  40. continue;
  41. if(in[i] == INF)
  42. return -1;//除了根以外有点没有入边,则根无法到达它 说明它是独立的点 一定不能构成树形图
  43. }
  44. //2.找环
  45. int cnt = 0;//记录环数
  46. memset(id, -1, sizeof(id));
  47. memset(vis, -1, sizeof(vis));
  48. in[root] = 0;
  49. for( i = 0; i < V; i++) //标记每个环
  50. {
  51. ret += in[i];//记录权值
  52. int v = i;
  53. while(vis[v] != i && id[v] == -1 && v != root)
  54. {
  55. vis[v] = i;
  56. v = pre[v];
  57. }
  58. if(v != root && id[v] == -1)
  59. {
  60. for(int u = pre[v]; u != v; u = pre[u])
  61. id[u] = cnt;//标记节点u为第几个环
  62. id[v] = cnt++;
  63. }
  64. }
  65. if(cnt == 0)
  66. break; //无环 则break
  67. for( i = 0; i < V; i++)
  68. if(id[i] == -1)
  69. id[i] = cnt++;
  70. //3.建立新图 缩点,重新标记
  71. for( i = 0; i < E; i++)
  72. {
  73. int u = edge[i].u;
  74. int v = edge[i].v;
  75. edge[i].u = id[u];
  76. edge[i].v = id[v];
  77. if(id[u] != id[v])
  78. edge[i].w -= in[v];
  79. }
  80. V = cnt;
  81. root = id[root];
  82. }
  83. return ret;
  84. }
  85. int main()
  86. {
  87. // freopen("数据\\1009.in","r",stdin);
  88. // freopen("数据\\fxxl1009.out","w",stdout);
  89. int i,j,cas;
  90. scanf("%d",&cas);
  91. while(cas--)
  92. {
  93. scanf("%d%d",&n,&m);
  94. for(i=0;i<m;i++)
  95. {
  96. scanf("%d%d%lld", &edge[i].u, &edge[i].v, &edge[i].w);
  97. edge[i].u--; edge[i].v--;
  98. edge[i].w*=1000;
  99. if(edge[i].v==n-1)
  100. edge[i].w+=(999-edge[i].u);
  101. edge[i].w*=-1;
  102. }
  103. ll ans = Directed_MST(0,n,m);
  104. // cout<<ans<<' '<<ans_father<<endl;
  105. ans*=-1;
  106. ans_father=(999-ans%1000)+1;
  107. ans=ans/1000;
  108. printf("%lld %d\n",ans,ans_father);
  109. }
  110. return 0;
  111. }
  112.  
  113. /*
  114.  
  115. 1
  116. 3 8
  117. 1 2 10
  118. 2 1 10
  119. 2 3 10
  120. 3 2 10
  121. 1 3 10
  122. 3 1 10
  123. 2 1 100
  124. 3 1 100
  125.  
  126. */

  

 

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. HDU 6141 I am your Father!(最小树形图+权值编码)

    http://acm.hdu.edu.cn/showproblem.php?pid=6141 题意: 求最大树形图. 思路: 把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决. 有个 ...

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

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

  4. hdu 1178 Heritage from father (推导)

    题意: 有一个金币堆的金字塔,最上层就有一个金币,以后的i层都是边长为i的实心三角形,给你层数,问:一共有多少个金币?(用科学计数法表示,并且保留两位小数) 解题思路: 根据题意可知求出1*n+2*( ...

  5. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  6. HDU 2376 树形dp|树上任意两点距离和的平均值

    原题:http://acm.hdu.edu.cn/showproblem.php?pid=2376 经典问题,求的是树上任意两点和的平均值. 这里我们不能枚举点,这样n^2的复杂度.我们可以枚举每一条 ...

  7. HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)

    Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Su ...

  8. hdu 4035 2011成都赛区网络赛E 概率dp ****

    太吊了,反正我不会 /* HDU 4035 dp求期望的题. 题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点 ...

  9. HDU 1102 最小生成树裸题,kruskal,prim

    1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> ...

随机推荐

  1. HashMap集合-遍历方法

    # HashMap集合-遍历方法 先定义好集合: public static void main(String[] args) { Map<String,String> onemap=ne ...

  2. Python解Leetcode: 226. Invert Binary Tree

    leetcode 226. Invert Binary Tree 倒置二叉树 思路:分别倒置左边和右边的结点,然后把根结点的左右指针分别指向右左倒置后返回的根结点. # Definition for ...

  3. Kubernetes组件-CronJob(定时任务)

    ⒈简介: Kubernetes的Job资源在创建时会立即运行pod.但是许多批处理任务需要在特定的时间运行,或者在指定的时间间隔内重复运行.在Linux和类UNIX操作系统中,这些任务通常被称为cro ...

  4. vue的基本语法

    在学习vue之前,我们应了解一下什么是vue.js? 什么是Vue.js? Vue.js是目前最后一个前端框架,React是最流行的一个前端框架(react除了开发网站,还可以开发手机App,Vue语 ...

  5. Python基础『一』

    内置数据类型 数据名称 例子 数字: Bool,Complex,Float,Integer True/False; z=a+bj; 1.23; 123 字符串: String '123456' 元组: ...

  6. EF Core的级联删除

    级联删除由DeleteBehavior的枚举值来设置: 行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响 Cascade 删除实体 删除实体 ClientSetNull 外键属性 ...

  7. VUE实现简单的全选/全不选

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. TypeScript入门六:TypeScript的泛型

    泛型函数 泛型类 一.泛型函数 在泛型函数之前,先简单的描述一下泛型,将变量定义成泛型可以在使用变量时来决定它的类型.什么意思呢?假如现在有一个函数,可能出现参数和返回值出现多种情况的现象,只有在调用 ...

  9. DX使用随记--GroupControl

    1. 创建按钮: (1)添加引用:Imports DevExpress.XtraEditors.ButtonsPanelControl (2)添加按钮语句:GroupControl1.CustomHe ...

  10. SpringBoot之Redis访问(spring-boot-starter-data-redis)

    依赖注入: <!--dependency for redis--> <!-- https://mvnrepository.com/artifact/org.springframewo ...