zoukankan      html  css  js  c++  java
  • hdu 1233 还是畅通工程

    /*


    Krusal
    只与边的个数有关
    算法:
    1:将个边按权值大小进行排序
    2: 遍历一次,找出最小权值的边,(条件:此次找出的边不能和已加入最小生成树集合的边构成环)
       若符合条件,则加入最小生成树的集合中。不符合则继续找。

    3:重复上述步骤,直到找到n-1条边(假设有n个节点)


    */


    #include"stdio.h"
    #include"stdlib.h"
    int set[5000];
    struct node
    {
    	int a,b,dis;
    }aa[5002];
    int find(int x)
    {
    	int r,i;
    	r=x;
    	while(r!=set[r])
    	r=set[r];
    	while(set[x]!=r)
    	{
    		i=set[x];
    		set[x]=r;
    		x=i;
    	}
    	return r;
    }
    int cmp(const void*a,const void*b)
    {
    	struct node *c,*d;
    	c=(struct node*)a;
    	d=(struct node*)b;
    	return c->dis-d->dis;
    }
    
    
    int main()
    {
    	int n,m,i,j,ans;
    	int x,y;
    
    
    	while(scanf("%d",&n)!=EOF&&n)
    	{
    		m=n*(n-1)/2;
    		for(i=0;i<=5000;i++)
    			set[i]=i;
    		for(i=0;i<m;i++)
    			scanf("%d%d%d",&aa[i].a,&aa[i].b,&aa[i].dis);
    		qsort(aa,m,sizeof(aa[0]),cmp);
    		ans=0;
    		for(i=0;i<m;i++)
    		{
    			x=find(aa[i].a);
    			y=find(aa[i].b);
    			if(x!=y)
    			{
    				ans+=aa[i].dis;
    				if(x<y) set[y]=x;
    				else set[x]=y;
    			}
    		}
    		printf("%d\n",ans);
    	}
    	return 0;
    }

    普利姆(Prime)算法(只与顶点相关)

     

    算法描述:

    普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠

     

    密网的最小生成树,时间复杂度为O(n*n)。

    算法过程:

    1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分

     

    是未处理的结点(B集合)。

    2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中

     

    顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。

    3.递归重复步骤2,直到B集合中的结点为空,结束此过程。

    4.A集合中的结点就是由Prime算法得到的最小生成树的结点,依照步骤2的结点连接

     

    这些顶点,得到的就是这个图的最小生成树。

    #include"stdio.h"
    #include"string.h"
    #define INF 99999999
    int map[100][100],dis[100];
    int mark[100];
    int n;
    void prime()
    {
    	int i,j,k,min,sum;
    	for(i=1;i<=n;i++)
    		dis[i]=map[1][i];
    	memset(mark,0,sizeof(mark));
    	mark[1]=1;
    	sum=0;
    	for(i=2;i<=n;i++)
    	{
    		min=INF;
    		for(j=2;j<=n;j++)
    		{
    			if(!mark[j]&&dis[j]<min)
    			{
    				min=dis[j];k=j;
    			}
    		}
    		sum+=min;
    		mark[k]=1;
    		for(j=2;j<=n;j++)
    		{
    			if(!mark[j]&&map[j][k]<dis[j])
    				dis[j]=map[j][k];
    		}
    	}
    	printf("%d\n",sum);
    }
    int main()
    {
    	int i,j,x,y,d;
    	while(scanf("%d",&n)!=EOF&&n)
    	{
    		memset(map,0,sizeof(map));
    		for(i=1;i<=n;i++)
    			map[i][i]=INF;
    		j=n*(n-1)/2;
    		for(i=0;i<j;i++)
    		{
    			scanf("%d%d%d",&x,&y,&d);
    			map[x][y]=map[y][x]=d;
    		}
    		prime();
    	}
    	return 0;
    }
    





  • 相关阅读:
    socket发送文字、图片、文件---基于python实现
    python socket详解
    loadrunner socket协议问题归纳(6)
    Hash算法解决冲突的四种方法
    while循环 运算符和编码
    python初识
    js中forEach,for in,for of循环的用法详解
    设计模式之MVC和MVT
    mac 下的 tree 命令 终端展示你的目录树结构
    Mac查看进程
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365405.html
Copyright © 2011-2022 走看看