• 图论---最小生成树


    树是一种特殊的图,具有很多特殊的性质。生成树问题研究的是将图中的所有顶点保留,但只选择图中的部分边,得到一棵树(也就是图的生成树)的问题。最小生成树则是在这些生成树中,边权之和最小的生成树。

    可以使用prime算法或者kruskal算法求解最小生成树。

    生成树相关概念

    1、生成树定义
    在一个V个点的无向连通图中,取其中V-1条边,并连接所有的顶点,所得到的子图称为原图的一棵生成树
    2、树的属性
    树是图的一种特殊形态。图G是树当且仅当以下任意一个条件成立
    ①G有V-1条边,无环;
    ②G有V-1条边,连通;
    ③任意两点之间只有唯一的简单路径
    ④G连通,但任意删除一条边后就不连通。
    3、最小生成树
    在一个带权的无向连通图中,各边权和最小的一棵生成树即为原图的最小生成树
    4、最小边原则
    图中权值最小的边(如果唯一的话)一定在最小生成树上
    5、唯一性定理
    对于一个图G,如果图中的边权值都不相同,则图的最小生成树是唯一的,反之不然。

    Prime算法

    prim

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int INF=0X7ffffff/2;
    int vst[505];//vst[i]标记顶点i是否加入最小生成树 
    int d[505];//d[i]表示点i与当前生成树中的点有连边的边长最小值 
    int g[505][505],n,m,ans=0;
    void read()//读入数据,构建图 
    {
    	int i,j,x,y,w;
    	cin>>n>>m;
    	for(i=1;i<=n;i++)
    	  for(j=1;j<=m;j++)
    	     g[i][j]=INF;
        for(i=1;i<=m;i++)
    	{
    		cin>>x>>y>>w;
    		g[x][y]=g[y][x]=w;
    	 } 
    }
    void prim(int v0)
    {
    	int i,j,k,minn;
    	memset(vst,0,sizeof(vst));//初始化生成树点集合 
    	for(i=1;i<=n;i++) d[i]=INF;
    	d[v0]=0;
    	ans=0;
    	for(i=1;i<=n;i++)//选择n个点 
    	{
    		minn=INF;
    		for(j=1;j<=n;j++)//选择最小边 
    		   if(vst[j]==0&&minn>d[j])
    		     { minn=d[j];k=j; } 
            vst[k]=1;//标记 
            ans+=d[k]; 
            for(j=1;j<=n;j++)//修改d数组 
                if(vst[j]==0&&d[j]>g[k][j])
    			   d[j]=g[k][j]; 
    	}
    }
    int main()
    {
    	read();
    	prim(1);
    	cout<<ans<<endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    kruskal算法

    kruskal

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=100005;
    struct edge{int x,y,z;}a[maxn];
    int n,m,prt[maxn],ans=0,bj;
    bool cmp(edge x,edge y){return x.z<y.z;}
    int getfather(int x)//查找祖先
    {
    	if(prt[x]==x) return x;
    	prt[x]=getfather(prt[x]);
    	return prt[x];
     } 
     void kruskal()
     {
     	int f1,f2,k,i;
     	k=0;
     	for(i=1;i<=n;i++) prt[i]=i;
     	for(i=1;i<=m;i++)
     	{
     		f1=getfather(a[i].x);
     		f2=getfather(a[i].y);
     		if(f1!=f2)
     		{
     			ans=ans+a[i].z;
     			prt[f1]=f2;
     			k++;
     			if(k==n-1) break; 
    		 }
    	 }
    	 if(k<n-1){
    	 	cout<<"impossible"<<endl;
    	 	bj=0;
    	 	return;
    	 }
     }
     int main()
     {
     	cin>>n>>m;
    	 ans=0;bj=1;
    	 for(int i=1;i<=m;i++)
    	  cin>>a[i].x>>a[i].y>>a[i].z;
    	 sort(a+1,a+m+1,cmp); 
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    相关练习

    1、最小生成树
    2、买礼物

  • 相关阅读:
    LangChain入门:24.通过Baby AGI实现自动生成和执行任务
    【大数据Hive】hive select 语法使用详解
    可以提取图像文本的 5 大 Python 库
    AOP(面向切面编程)
    Spring Security loadUserByUsername传递多个参数
    关于tensorboard无法打开
    MyBatis 快速入门
    python爬虫之多线程threading、多进程multiprocessing、协程aiohttp 批量下载图片
    Onnxruntime之tensorrt加速
    为了生活而奔波
  • 原文地址:https://blog.csdn.net/qq_32431299/article/details/125612111