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

       题意是有n个点(0--n-1),m条有向边,问以那个点作为起点使得最小生成树的权值最小,如果可以构成输出权值和顶点编号,否则输出impossible。

       对于这种不定根的题,在不知道虚根这个东西前我是暴力去写的,就是以每一个点都为顶点跑一遍朱刘算法求最小值,按理说因该是TLE才对,然后被我写WA了....然后来说一下用虚根的写法,很巧妙...对于已经建好的图的基础上再额外的加一个点,让这个点与其他的n个点都连一条边,边的权值为前n个点的权值之和再+1,所以现在是有n+1个点,m+n条边。

       例如题中的第二个样例,以新加的这个4这个点为根,会得到如下图的图。

                 

       然后我们以编号为4的点为根,跑朱刘算法,用橙色线标记出来的就是一个最小生成树,所以最后的生成树的权值就是ans-sum(sum是前m条边的权值之和+1)。对于找最小根的情况,我们需要在寻找最小弧的时候判断一下就好了,因为存的边是先存的前m条边,再存的后n条边,所以对于前m条边都进行完入边操作后就剩下0这个结点还没有入边,所以在后n条边中更新了0这个点的入边,而且此时0点的最小入边的权值就是71,所以就可以判断出0就是我们要找的最小根了,所以标记一下当前的边的编号,然后减去m即为所求。如果最后跑出来的结果是大于等于2*sum,就说明权值为71的边选了两条,所以不能构成最小生成树,这种情况判断一下就好了。虚根的写法不难理解,结合代码想一下就好了。


AC代码:

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;
const int MAXM = 10005;
struct Edge{int u, v, cost;
}edge[MAXM];
int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN];
int n,m,root,pos,num;void add(int u,int v,int w){edge[num].u = u;edge[num].v = v;edge[num++].cost = w;
}int solve()
{int res = 0;while (1){for(int i=0;i<n;i++) in[i] = INF;for(int i=0;i<num;++i){int u = edge[i].u, v = edge[i].v;if(edge[i].cost < in[v] && u != v){pre[v] = u;in[v] = edge[i].cost;if(u == root) pos = i;      // 标记最小根}}for (int i = 0; i < n; i++){if (i != root && in[i] == INF) return -1;}int tn = 0;memset(id, -1, sizeof(id));memset(vis, -1, sizeof(vis));in[root] = 0;for(int i = 0; i < n; i++){res += in[i];int v = i;while(vis[v] != i && id[v] == -1 && v != root){vis[v] = i;v = pre[v];}if(v != root && id[v] == -1){for(int u = pre[v]; u != v ; u = pre[u]) id[u] = tn;id[v] = tn++;}}if (tn == 0) break;for (int i = 0; i < n; i++){if(id[i] == -1) id[i] = tn++;}for (int i = 0; i < num; i++){int v = edge[i].v;edge[i].u = id[edge[i].u];edge[i].v = id[edge[i].v];if (edge[i].u != edge[i].v) edge[i].cost -= in[v];}n = tn;root = id[root];}return res;
}int main()
{while(~scanf("%d%d",&n,&m)){int sum = 0;num = 0;for(int i=0;i<m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);sum += w;add(u, v, w);}sum ++;for(int i=0;i<n;i++){add(n, i, sum);}n ++;root = n - 1;int ans = solve();if(ans == -1 || ans >= 2 * sum){puts("impossible");}else printf("%d %d\n", ans - sum, pos - m);puts("");}return 0;
}

HDU 2121 Ice_cream’s world II(最小树形图+虚根)相关推荐

  1. HDU 2121 Ice_cream’s world II (最小树形图+虚根)

    题意:有n个点(0~n-1),m条有向边,问以哪个点作为起点使得最小生成树的权值最小,如果可以构成输出权值和顶点编号,否则输出impossible. 题解:最小树形图+虚根 还好做了这题,板子有点问题 ...

  2. hdu 2121 Ice_cream’s world II

    无固定根节点的最小树形图,添加一个人工根节点,人工根节点到每个节点的权值sum>(所有边权值之和), 求出结果减去sum,只有人工根节点跟一个节点相连时才会有解,如果结果大于等于sum,则人工节 ...

  3. HDU - 2121 Ice_cream’s world II(朱刘算法+虚根)

    题目大意:给你N个点,M条有向边,问以哪个点为根结点时,能使最小生成树总权值达到最小,输出总权值和根. 如果构不成最小生成树,另外输出 解题思路:这题很巧妙,暴力枚举的话,肯定TLE,所以,这题就需要 ...

  4. hdu 2121 最小树形图 +虚根

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 题意: n个城市,m条单向边,每条边都有一个权值,现在要你求出这样一个节点,由这个节点出发能走遍 ...

  5. HDU 4009 Transfer water (最小树形图+虚根)

    题意:有一个村庄需要修建供水系统.每户居民的房子都有一个三维坐标,每户居民可以选择自己挖井或者从其他居民家里引水.挖水井和引水分别需要花费不同的钱.每户居民有一个意愿表,只愿意对表内的居民家供水.最后 ...

  6. hdu4966 最小树形图+虚根

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

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

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

  8. hdu 4009 Transfer water(最小树形图模板)

    题目链接:点击打开链接 Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Ja ...

  9. GGS-DDU 【HDU - 4966】【最小树形图】

    题目链接 最小树形图讲解 一道最小树形图的裸题,我们只需要对于在同一学科的由高等级逐一指向低等级的边建为0权值即可,另外的边,建立成有向边即可. #include <iostream> # ...

最新文章

  1. Linux系统备份策略探讨
  2. JDBC—01—JDBC简介;JDBC常用接口与类;
  3. php如何压缩txt文件怎么打开,PHP-压缩txt文件,同时保持文件扩展名
  4. JPA中实现单向一对多的关联关系
  5. 【机器视觉】 dev_unmap_prog算子
  6. 如何向Spring Bean 中注入java.util.Properties?
  7. [转载] python迭代器、生成器和装饰器
  8. 博客资源网小程序带流量主激励视频收益
  9. Oracle学习 第18天 .NET连接Oracle
  10. 序列化和反序列化(八)——Externalizable接口
  11. 使用xml和java代码混合控制UI界面
  12. 探讨职业化的表达方式
  13. 开源微博系统Xweibo的一些主要函数注释
  14. Python 音频生成器
  15. finalcut剪切快捷键_【FCPX】Final Cut Pro X 常用快捷键大全
  16. 大白话讲清楚JVM里的方法区、永久代以及元空间
  17. 如何用MATLAB读取大文本文件
  18. 梦三显示服务器列表,梦三国开服表_梦三国开服时间表_梦三国最新开服_9K9K手游网...
  19. 除开各种设置自动调节开关,笔记本电脑屏幕亮度自动变亮变暗解决办法
  20. RMA Line stuck in AWAITING_RETURN or AWAITING_RETURN_DISPOSITION (文档 ID 378221.1)

热门文章

  1. 狼的故事17:大结局
  2. 西南科技大学 Python程序设计 班长选举
  3. 热更新原理及实践注意
  4. 深度学习部署(十八): CUDA RunTime API _wa_仿射变换的实现
  5. 个人网站接入live2d详细教程
  6. md文档html显示+toc,使用md-toc.js来生成文章目录
  7. 概念:伪随机数、种子以及C中的随机函数
  8. nvidia显卡,驱动以及cuda版本对应查询
  9. [好消息]大连.NET俱乐部QQ群开放注册~~~注册有好礼!
  10. MT4MT5EA编程跟单系统EA