最小树形图(刘朱算法)记录
来源:互联网 发布:中国经济走势 知乎 编辑:程序博客网 时间:2024/06/06 08:45
算法步骤:
1、建立最短边集(有向边), 注意除去自环(自己连向自己)
in[v] 记录最小权值,pre[v] 记录边的起点
例子:
边1 A->B 权:5
边2 C->B 权:3
则 in[B]=3 pre[B]=C
若集合建立完毕后,仍有孤立的点,则不存在最小树形图。
2、查找有向环,并把它缩成一个点
方法: 设置环中点的编号 id[x]=newnode;
3、若没有 有向环则已经构建最小树形图 ,输出结果
否则,把剩余不在环中的点收集起来。
再更新边
int v=Edge.to;
Edge.from=id[Edge.from]
Edge.to=id[Edge.to]
重要:
如果不构成自环,即Edge.from!=Edge.to
则 Edge.cost-=in[v]
模板:
// 假设点集1-n 边集0- m-1 起点是1#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn=200;const int maxm=1e4+10;const int INF=0x3f3f3f3f;struct Edge{ int from,to,cost; Edge() {} Edge(int f,int t,int c):from(f),to(t),cost(c) {} }edges[maxm]; int pre[maxn];int n,m;int in[maxn],id[maxn],vis[maxn]; //vis记录环void init() //建图{ scanf("%d%d",&n,&m); int cnt=0; for (int i=0;i<m;i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); if (u!=v) edges[cnt++]=Edge(u,v,c); //除去自环 } m=cnt;}int work(int s) //最小树形图算法{ int ret=0; while(1) { for (int i=1;i<=n;i++) in[i]=INF; //建立最短边集 for (int i=0;i<m;i++) { Edge e=edges[i]; if (e.to!=e.from && in[e.to]>e.cost) { //易错!! e.to!=e.from 自环 pre[e.to]=e.from; in[e.to]=e.cost; } } for (int i=1;i<=n;i++) { if (i!=s&&in[i]==INF) return -1; //存在孤立点 不存在最小树形图 } int np=in[s]=0; memset(vis,-1,sizeof(vis)); memset(id,-1,sizeof(id)); for (int i=1;i<=n;i++) { ret+=in[i]; int v=i; while (vis[v]!=i&&id[v]==-1&&v!=s) { //不找到环 不存在其他环中 不是根 vis[v]=i; v=pre[v]; } if (id[v]==-1&&v!=s) { //找到有向环(因第一个条件而跳出while, 即满足后两个条件) np++; for (int u=pre[v];u!=v;u=pre[u]) { id[u]=np; } id[v]=np; } } if (np==0) break; for (int i=1;i<=n;i++) //收集非环点 if (id[i]==-1) id[i]=++np; for (int i=0;i<m;i++) { //重新处理边 int u=edges[i].from; int v=edges[i].to; edges[i].from=id[edges[i].from]; edges[i].to=id[edges[i].to]; if (edges[i].from!=edges[i].to) { edges[i].cost-=in[v]; } } n=np; s=id[s]; //新点数,新起点 } return ret;}int main(){ init(); int ans=work(1); if (~ans) printf("%d\n",ans); else printf("impossible\n"); return 0;}
0 0
- 最小树形图(刘朱算法)记录
- 最小树形图(刘朱算法)
- 最小树形图(朱-刘算法)
- 最小树形图(朱-刘算法)
- 最小树形图(朱-刘算法)
- 最小树形图(朱-刘算法)
- bzoj4349&2260 最小树形图(商店购物)(朱刘算法 最小树形图)
- BZOJ 4349: 最小树形图(最小树形图->朱刘算法)
- 最小树形图 模版--朱刘算法
- hdu4966 最小树形图 /刘朱算法
- 最小树形图 朱刘算法
- 最小树形图 朱刘算法
- 最小树形图(朱刘算法)
- 最小树形图-朱刘算法
- 最小树形图 朱刘算法【转载】
- 最小树形图/朱刘算法……表示稍微记录一下
- 最小树形图模板(朱刘算法)
- 最小树形图(朱刘算法模板)
- OpenCV学习日记3
- Android实现类似QQ头像点击打开相册或者拍照,并获取裁剪后的图片
- 用flask开发个人博客(26)—— 利用config.py配置文件动态的创建不同的Flask对象
- C++构造函数之委托构造函数
- 解决Linux下多个进程或线程同时对一个文件进行写操作问题
- 最小树形图(刘朱算法)记录
- 一款轻量的分布式配置管理平台
- Petit FatFS在STC12C5A60S2实现移植
- OpenCV22(灰度共现矩阵/灰度共生矩阵)
- 记录一下python的数据结构
- bonita BPM-----identity API
- package bufio: unrecognized import path "bufio" 编译ngrok服务端
- 总结
- Android的计量单位px,in,mm,pt,dp,dip,sp