定义:一个有向图,存在从某个点为根的,可以到达所有点的一个最小生成树,则它就是最小树形图。

朱刘算法实现过程: 【在选出入边集后(看步骤1),若有向图中不存在有向环,说明该图就是最小树形图】

1,选入边集——找到除root点之外,每一个点的所有入边中权值最小的,用数组in[]记录下这个最小权值,用pre[]记录到达该点的前驱;(若图中存在独立点,最小树形图是不存在的,所以在该步骤结束后,要判断一下)

2,找有向环,并用数组id[]记录节点所属环的编号。

3,找到环后,缩点,并更新权值。(感觉和SCC缩点差不多)

4,以环数为下一次查找的点数,继续执行上述操作,直到没有环 或者 判定出不存在最小树形图为止。

给个图:

详看代码,有详细注释:点的编号是从0开始的

/*
最小树形图
朱刘算法模板
时间复杂度O(nm)
数据为int型
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1010
#define MAXM 1000000+10
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
int from, to, cost;
};
Edge edge[MAXM];
int pre[MAXN];//存储父节点
int vis[MAXN];//标记作用
int id[MAXN];//id[i]记录节点i所在环的编号
int in[MAXN];//in[i]记录i入边中最小的权值
int zhuliu(int root, int n, int m, Edge *edge)//root根 n点数 m边数
{
int res = 0, u, v;
while(1)
{
for(int i = 0; i < n; i++)
in[i] = INF;//初始化
for(int i = 0; i < m; i++)
{
Edge E = edge[i];
if(E.from != E.to && E.cost < in[E.to])
{
pre[E.to] = E.from;//记录前驱
in[E.to] = E.cost;//更新
}
}
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];//累加
v = i;
//找图中的有向环 三种情况会终止while循环
//1,直到出现带有同样标记的点说明成环
//2,节点已经属于其他环
//3,遍历到根
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++;//环数累加
//对有向环缩点 和SCC缩点很像吧
for(int i = 0; i < m; i++)
{
v = edge[i].to;
edge[i].from = id[edge[i].from];
edge[i].to = id[edge[i].to];
//<u, v>有向边
//两点不在同一个环 u到v的距离为 边权cost - in[v]
if(edge[i].from != edge[i].to)
edge[i].cost -= in[v];//更新边权值 继续下一条边的判定
}
n = tn;//以环总数为下次操作的点数 继续执行上述操作 直到没有环
root = id[root];
}
return res;
}
int main()
{
int N, M;//N个点 M条有向边
while(scanf("%d%d", &N, &M) != EOF)
{
getMap();//建图 注意去除自环 自己到自己的权值为无穷大
int ans = zhuliu(0, N, M, edge);
if(ans == -1)
printf("-1\n");//不存在
else
printf("%d\n", ans);
}
return 0;
}

最小树形图——朱刘算法(Edmonds)的更多相关文章

  1. POJ 3164 Command Network ( 最小树形图 朱刘算法)

    题目链接 Description After a long lasting war on words, a war on arms finally breaks out between littlek ...

  2. poj3164(最小树形图&朱刘算法模板)

    题目链接:http://poj.org/problem?id=3164 题意:第一行为n, m,接下来n行为n个点的二维坐标, 再接下来m行每行输入两个数u, v,表点u到点v是单向可达的,求这个有向 ...

  3. POJ 3164 Command Network 最小树形图 朱刘算法

    =============== 分割线之下摘自Sasuke_SCUT的blog============= 最 小树形图,就是给有向带权图中指定一个特殊的点root,求一棵以root为根的有向生成树T, ...

  4. 最小树形图--朱刘算法([JSOI2008]小店购物)

    题面 luogu Sol 首先设一个 \(0\) 号点,向所有点连边,表示初始价值 显然这个图的一个 \(0\) 为根的最小有向生成树的边权和就是每个买一次的最小价值 再买就一定能优惠(包含 \(0\ ...

  5. 洛谷P4716 【模板】最小树形图(朱刘算法)

    题意 题目链接 Sol 朱刘算法?感觉又是一种神仙贪心算法 大概就是每次贪心的用每个点边权最小的入边更新答案,如果不行的话就缩起来找其他的边 不详细说了,丢链接走人.. #include<bit ...

  6. POJ - 3164-Command Network 最小树形图——朱刘算法

    POJ - 3164 题意: 一个有向图,存在从某个点为根的,可以到达所有点的一个最小生成树,则它就是最小树形图. 题目就是求这个最小的树形图. 参考资料:https://blog.csdn.net/ ...

  7. bzoj 4349 最小树形图——朱刘算法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4349. 学习博客:http://www.cnblogs.com/xzxl/p/7243466 ...

  8. poj 3164 Command Network (朱刘算法)

    题目链接: http://poj.org/problem?id=3164 题目大意: 有n个点(用坐标表示)各点编号分别为1—>n,m条单向路,问能否存在一个花费价值最小的网络,能使从1点到达任 ...

  9. UVa11183 Teen Girl Squad, 最小树形图,朱刘算法

    Teen Girl Squad  Input: Standard Input Output: Standard Output You are part of a group of n teenage ...

随机推荐

  1. Jmeter3.0 中文乱码的解决方法

    在Body Data中输入中文时,发现是乱码,如下图 这种情况在jmeter3.0的版本中才会产生,由于3.0中优化body data后,使用默认的字体(Consolas)不支持汉字的显示. 解决方法 ...

  2. oracle 备份脚本

    本文是一个shell脚本.主要用于Oracle 数据库备份.默认情况下,在周一晚上进行全备.其他时间进行累积增量备份. 使用方法: 假如脚本保存名为: oracle_backup.sh 使用方法为 o ...

  3. 步步為營-96-MyMVC2

    說明:地址欄中的URL還存在一些不足之處 地址欄中最好能是http"www.sss.com/asdf/aaa 1.1 模擬路由的原理:創建Routing文件夾,并添加URLRoutingMo ...

  4. salt上编写了备份日志的脚本

    我在salt上编写了备份日志的脚本,在/opt/CardServer下的主程序目录只保留当天的日志,/opt/log_del目录会保存7天的日志.salt * state.sls script.log ...

  5. 微信jssdk分享功能开发

    先理解下分享: 在app端 ,经常能看见 分享按钮的功能,(分享给朋友,分享到朋友圈,分享到QQ空间等等): https://open.weixin.qq.com/(微信开发平台),这需要到开放平台注 ...

  6. 在IDEA中编写Spark的WordCount程序

    1:spark shell仅在测试和验证我们的程序时使用的较多,在生产环境中,通常会在IDE中编制程序,然后打成jar包,然后提交到集群,最常用的是创建一个Maven项目,利用Maven来管理jar包 ...

  7. Spring MVC基础知识整理➣环境搭建和Hello World

    概述 Spring MVC属于SpringFrameWork的产品,采用Model-View-Controller进行数据交互,已经融合在Spring Web Flow里面.Spring 框架提供了构 ...

  8. [BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

    题解: 解法1: 单调栈优化 首先发现一个性质就是 如果当前从i转移比从j转移更加优秀 那么之后就不会从j转移 所以我们考虑利用这个性质 我们要维护一个队列保证前一个超过后一个的时间单调不减 怎么来维 ...

  9. ipython启动 自动导入模块 自动%logstart

    1. 参考 启动ipython或python解释器自动导入组件(例如:numpy) http://ipython.org/ipython-doc/stable/config/intro.html#se ...

  10. Bean Shell常用内置变量总结

    JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下: log:写入信息到jmeber.log文件,使用方法:log.info( ...