MST唯一性判断

2024-02-10 07:18
文章标签 判断 唯一性 mst

本文主要是介绍MST唯一性判断,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

模板题: fzu2087 统计树边

解法(mengxiang000000的博客 )

思路:用kruskal算法模拟生成树的过程。同时也是一个贪心生成树的过程,我们知道,生成的树的边权值和是一定的,那么对于边的替换的值也是能够确定的:只有权值相同的边才有可能是另一种生成树方法的边。

然后我就呆萌的记录有多少重边权值的边,然后加上n-1,开开心心的提交,实力WA。一组数据就可以干掉我:
3 3
1 2 1
1 2 2
2 3 1

所以记得一定不要跟我犯一样的错误,我们需要的是动态判断一条边权值相同的边能否可能是另一种生成树方法的边。我们直接在kruskal算法过程中加上动态判断的成分就可以了,那么要如何判断呢?遍历每一条边的时候,如果有相同权值的边,像kruskal一样的判断条件,判断这条边能否加入生成树中即可。

kruskal算法判断一条边是否能够贪心的加入生成树中:

for(int i=0;i<m;i++)   {  if(find(a[i].x)!=find(a[i].y))  {  zhongquanzhi+=a[i].w;  merge(a[i].x,a[i].y);  }   }

我们对同权值的边判断能否加入生成树中,并且别忘记对边要进行入树:

for(int i=0;i<m;i=j)  
{  for(j=i;a[i].w==a[j].w;j++)  {  if(find(a[j].x)!=find(a[j].y))  {  output++;  }  }  for(j=i;a[i].w==a[j].w;j++)  {  if(find(a[j].x)!=find(a[j].y))  {  merge(a[j].x,a[j].y);  }  }  
}  

简而言之
如果安全,则先不Union,先统计最小生成树的边数,待统计完后再Union;
poj1679 与此题类似

fzu2087

#include<iostream>
#include<algorithm>
using namespace std;
const int  maxn=100005;typedef struct node{int st,ed,cost;
}Edge ;
Edge edge[100005];
int cmp(Edge a,Edge b){return a.cost<b.cost;
}int fa[maxn];
void init(){for(int i=0;i<maxn;i++)fa[i]= i;
}int Find(int x){if(fa[x] == x)   return fa[x];else  return fa[x] = Find(fa[x]);
}void Union(int x,int y){int fx=Find(x),fy=Find(y);if(fx!= fy)fa[fx] = fy;
}int main(){ios_base::sync_with_stdio(false);int T;cin>>T;while(T--){int n,m,t1,t2,t3;cin>>n>>m;for(int i=0;i<m;i++){cin>>t1>>t2>>t3;edge[i].st=t1,edge[i].ed=t2,edge[i].cost=t3;}sort(edge,edge+m,cmp);int bianshu=0;int tot_cost = 0;init();for(int i=0;i < m ;i++){for(int j=i;edge[j].cost == edge[i].cost;j++)if(Find(edge[j].st)!= Find(edge[j].ed))bianshu++;for(int j=i;edge[j].cost == edge[i].cost;j++)if(Find(edge[j].st)!= Find(edge[j].ed) )Union(edge[j].st,edge[j].ed),tot_cost+=edge[j].cost;}cout<<bianshu<<endl;}
}

这篇关于MST唯一性判断的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/696474

相关文章

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

linux 判断某个命令是否安装

linux 判断某个命令是否安装 if ! [ -x "$(command -v git)" ]; thenecho 'Error: git is not installed.' >&2exit 1fi

shell循环sleep while例子 条件判断

i=1# 小于5等于时候才执行while [ ${i} -le 5 ]doecho ${i}i=`expr ${i} + 1`# 休眠3秒sleep 3doneecho done 参考 http://c.biancheng.net/cpp/view/2736.html

(二)Vue.js 条件判断 20170818

条件判断 (一)v-if  使用 概念:v-if  其实说白了就是类似于java里面的判断语句,在vue.js中经常跟 template一起使用  1.jsp 代码 <template v-if="false"><label>符亮星</label><br/><label>职业爱好:编码制造方便</label></template> 设置为false时就会隐藏掉 结果图

如何判断一个数组中是否包含一个字符或字符串

第一种方法:遍历数组 String[] arr1 = {"1","2","3","4","6","7"}; for (int i = 0; i < arr1.length; i++) { if("5".equals(arr1[i])) { System.out.println("包含"); }else { System.out.println("不包含"); } } 第二种方法:先把数组