• 最小生成树-kruskal


    kruskal算法,没有进行算法复杂度分析

    判断俩个结点是否在同一个树上使用了dfs,比较low的写法

    输入数据

    //第一行,结点数,结点数,边数

    9 9 14
    a b 4
    b c 8
    c d 7
    a h 8
    b h 11
    h i 7
    i c 2
    i g 6
    c f 4
    d f 14
    d e 9
    f e 10
    g h 1
    g f 2

    //============================================================================
    // Name        : kruskal.cpp
    // Author      : caicai
    // Version     :
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <memory.h>
    using namespace std;
    
    struct Node
    {
    	char s;
    	char e;
    	int w;
    };
    
    void printMap(int r, int a[][100])
    {
    	for(int i = 0; i < r; i++)
    	{
    		for(int j = 0; j < r; j++)
    		{
    			printf("%-3d", a[i][j]);
    		}
    		cout << endl;
    	}
    	cout << endl;
    }
    /**
     * 边根据权重从小到大排序
     */
    void sortEdge(Node edges[], int total)
    {
    	Node temp;
    	for(int i = 0; i < total; i++)
    	{
    		for(int j = 1; j < total; j++)
    		{
    			if(edges[j - 1].w > edges[j].w)
    			{
    				temp = edges[j - 1];
    				edges[j - 1] = edges[j];
    				edges[j] = temp;
    			}
    		}
    	}
    }
    void printEdges(Node edges[], int total)
    {
    	for(int i = 0; i < total; i++)
    		cout << edges[i].s << " " << edges[i].e << " " << edges[i].w << endl;
    }
    void dfs(int a[][100], int r, int s, int e, int* ok, int vis[])
    {
    	for(int i = 0; i < r; i++)
    	{
    		if(vis[i] || a[s][i] == 0)
    		{
    			//走过,不存在的路
    			continue;
    		}
    		if(i == e)
    		{
    			//可到
    			*ok = 0;
    			return;
    		}
    		vis[i] = 1;
    		//从当前结点出发,不需要回溯,如果当前结点到不了,从其他结点到当前结点同样是到不了
    		dfs(a, r, i, e, ok, vis);
    	}
    }
    void kruskal(int a[][100], int r, Node edges[], int et)
    {
    	/**
    	 * 图G n个结点,刚开始每一个结点都一个单独的结点,并没有与任何结点连接
    	 * 将边按照权值从小到大排序
    	 * 循环边集合,检查该边连接的俩个点,是否在同一个树上,如果是,不要,如果不是,加入到最小生成树中
    	 * 怎么检查,a到b是否有一个条路
    	 * 检查是否在同一个树中,dfs检查
    	 */
    	/*
    	 *1初始化:生成的树为空,总权值为0
    	 *2循环:每一次循环边,加入到数组a,数组a中包含n棵树,对于每一颗树,加入的边的权值最小,所以加入此边后形成的树的总权也是最小的
    	 *     当俩棵树合并时,每棵的树的总权值也是最小的,所以相加后总权也是最小
    	 *3终止:每一次加入的边是权值也是最小的,所以循环终止时,总权也是最小的
    	 */
    	for(int i = 0; i < et; i++)
    	{
    		char s = edges[i].s;
    		char e = edges[i].e;
    		int ok = 1;
    		int vis[100];
    		memset(vis, 0, sizeof(vis));
    		//检查耗时
    		dfs(a, r, s - 'a', e - 'a', &ok, vis);
    		if(ok)
    		{
    			//不在同一颗树中,当前的边加入到树中
    			a[s - 'a'][e - 'a'] = edges[i].w;
    			//无向图
    			a[e - 'a'][s - 'a'] = edges[i].w;
    		}
    	}
    }
    int main()
    {
    	freopen("d:\2.txt", "r", stdin);
    	int r;
    	int te;
    	cin >> r >> r >> te;
    	char s, e;
    	int w;
    	int a[100][100];
    	Node edges[100];
    	int et = 0;
    	while (te--)
    	{
    		cin >> s >> e >> w;
    		//cout << s << " " << e << " " << w << endl;
    		Node node;
    		node.s = s;
    		node.e = e;
    		node.w = w;
    		edges[et++] = node;
    	}
    	sortEdge(edges, et);
    	printEdges(edges, et);
    	kruskal(a, r, edges, et);
    	printMap(r, a);
    	return 0;
    }
    

      输出

    g h 1
    i c 2
    g f 2
    a b 4
    c f 4
    i g 6
    c d 7
    h i 7
    b c 8
    a h 8
    d e 9
    f e 10
    b h 11
    d f 14
    0  4  0  0  0  0  0  0  0  
    4  0  8  0  0  0  0  0  0  
    0  8  0  7  0  4  0  0  2  
    0  0  7  0  9  0  0  0  0  
    0  0  0  9  0  0  0  0  0  
    0  0  4  0  0  0  2  0  0  
    0  0  0  0  0  2  0  1  0  
    0  0  0  0  0  0  1  0  0  
    0  0  2  0  0  0  0  0  0  
    

      

  • 相关阅读:
    用友U8存货分类通过DataTable生成EasyUI Tree JSON
    脚本加密与解密
    CKFinker 2.5.0.1 去demo标示
    C#压缩图片时保留原始的Exif信息
    Newtonsoft.Json转换强类型DataTable错误:Self referencing loop detected with type ......
    Access无法启动应用程序,工作组信息文件丢失,或是已被其他用户已独占方式打开
    C#获取邮件客户端保存的邮箱密码
    网站ASHX不执行故障
    水晶报表打印时出现:出现通信错误 将停止打印
    UILabel居上对齐居下对齐类别扩展
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/6953676.html
Copyright © 2020-2023  润新知