朱刘算法 有向图的最小生成树

朱刘算法

有向图的类Prim算法,找有向图的最小生成树

最小树形图

树形图:

  • 无有向环
  • 除了根节点外,每个点入度为1

以某个点为根的一棵有向树,其边权之和为图中所有树形图中是最小的称为最小树形图。

朱刘算法 O(nm)O(nm)O(nm)

(1) 除了根节点外对每个点选取一条边权最小的入边

(2)判断当前(选出的边)组成的图中有无环

​ 1.若无环:则说明当前图已经为构造好的最小生成树,算法结束

​ 2.若有环:进行第(3)步

(3)将构造的图进行强连通分量缩点,得到新图G′G'G,对于G′G'G中的所有边

​ 1.如果是环中的边:直接删去

​ 2.如果终点在环内(即新缩的点):更新此边权权值为W−W环内W-W_{环内}WW

​ 3.其他边:不变

然后继续从(1)开始迭代

当迭代完成后,所有选择的边的边权之和就是最终的答案。

邻接矩阵版本:

由于复杂度是 O(nm),因此在存储图的时候不需要背邻接表的板子,直接背邻接矩阵的即可。

板子:

const int N = 110,M=2e4+10,INF=1e8;
int n,m,r;
int d[N][N],bd[N][N],g[N][N];
int pre[N],bpre[N];
int dfn[N],low[N],timestamp,stk[N],top;
int id[N],scc_cnt;
bool st[N],ins[N];

void dfs(int u){
   
	st[u]=true;
	for(int i=1;i<=n;++i) 
		if(d[u][i]<INF&&!st[i])
			dfs(i); 
}

bool check_con(){
   
	memset(st,0,sizeof st);
	dfs(r);
	rep(i,1,n) 
		if(!st[i]) 
			return false;
	return true;
}

void tarjan(int u){
   
	dfn[u]=low[u]=++timestamp;
	stk[++top]=u;ins[u]=true;
	
	int j=pre[u];
	if(!dfn[j]){
   
		tarjan(j);
		low[u]=min(low[u],low[j]);
	}
	else if(ins[j]) low[u]=min(low[u],dfn
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值