zoukankan      html  css  js  c++  java
  • 数据结构 练习 22-并查集以及图的最小生成树

    前言

    本博客主要介绍并查集以及图的最小生成树。对于并查集,我们引入其基本概念,并分析其复杂度,最后利用并查集来分析最小生成树。

    并查集

    参考文献《算法导论》,博客 http://blog.csdn.net/dm_vincent/article/details/7655764
    并查集包括三个操作:make_set,find_set,union_set。

    链表表示:

           
    每个节点包括一个value,两个指针:一个指向下一个节点,一个指向头节点,还包括一个head和一个tail;
            每一个集合的代表为头结点,所以每个节点都得指向头结点,这样能迅速定位头结点。
    复杂度如下
           


    树根表示:

               树根表示,可以引入两种优化,按秩合并,路径压缩,当同时使用这优化时,最坏情况运行时间为:O(m*α(n)),m是总的操作次数,α(n)是一个增长及其缓慢的函数,通常α(n)<=4;所以最坏情况的复杂度可以看做是线性的;

    图的最小生成树

    图作为一种复杂的数据结构,前面 简单学习了图的遍历,接下来简单介绍最小生成树。

    相关概念:

      连通图:  对于无向图,任何两个顶点,他们之间都存在一条路径,则该无向图为连通图;

      强连通图:对于有向图,图中任意两个顶点之间都存在一条有向路径,则该有向图为强连通图;

      连通分量:非连通图中的各个连通子图成为该图的连通分量。

      

     解决最小生成树的方法,用到的思想贪心,并查集,递归。

    kruskal+并查集实现:

    #include <iostream>
    #include <string> 
    #include <cmath> 
    #include <algorithm>
    
    #define BUG puts("here!!!"); 
    using namespace std; 
    const int N = 5005; 
    int pre[N];//空间复杂度
    int n, m; 
    struct Node
    {    
    int u, v;   
    int w; }
    e[N];
    bool cmp(const Node a, const Node b)
    {   
    	return a.w < b.w;
    } 
    void makeSet(int n)
    {     
    	for(int i = 0; i <= n; i++)
    	{        
    		pre[i] = i;    
    	} 
    }
    int findSet(int a)
    {   
    	if(pre[a] == a) 
    		return a; 
    	return pre[a] = findSet(pre[a]);
    } 
    void kruskal()
    {     
    	int fu, fv, sum = 0,count = 0; 
    	sort(e, e+m, cmp);  
    	makeSet(n);   
    	for(int i = 0; i < m; i++) 
    	{         
    		fu = findSet(e[i].u);  
    		fv = findSet(e[i].v);  
    		if(fu != fv)
    		{          
    			sum += e[i].w;    
    			count++;         
    			if(count == n-1) break;   
    			pre[fv] = fu;    
    		}    
    	}   
    	cout << sum << endl; 
    }
    int main() 
    {     
    	while(cin >> n, n) 
    	{      
    		cin >> m; 
    		for(int i = 0; i < m; i++)
    		{            
    			cin >> e[i].u >> e[i].v >> e[i].w;    
    		}       
    		kruskal(); 
    	} 
    }

    kruskal是基于边的查找,先得对边排序,每次都查看当前最优,贪心的思想。

    prim算法:参考 点击打开链接

  • 相关阅读:
    【数据库】python访问mysql
    给vs2015添加EF
    SQL Sever 2008 R2版本添加Northwin数据库错误解决
    c#进程、定时器初步学习
    联动下拉框显示省市县
    第一次网站初尝试爬的坑
    关闭程序主窗体程序不结束,主要应用于登录界面
    基于三层架构的增删改查Get知识点
    python中的异常捕获怎么用?
    VS版本下载
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3187031.html
Copyright © 2011-2022 走看看