zoukankan      html  css  js  c++  java
  • 分量算法poj 1751 Highways 最小生成树之Kruskal(克鲁斯卡尔)算法

    上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下分量算法

        标题链接:http://poj.org/problem?id=1751

        大意是一个有n个都会的国度,已知有些都会有途径联通,问增加哪些途径使得所有的都会都可以彼此联通且价值最小,已价值是两个都会坐标的笛卡尔距离;

        就是一个纯粹的找最小生成树的题;

        

        首先讲所有边按权值从小到大排序,然后依次取最小边,如果联通的两个节点在两个联通分量上,则加入这条边,否则删除这条边;

        kruskal算法的要点就是判断两个节点是否是在一个联通分量上,于是够着个标记数组flag[];开始时候令flag[i]=i;这样就所有的节点都是一个联通分量,然后在取已有的m条边时,

        设边链接的节点为u,v,则令f[u]=f[v];就好了,这样两个节点就在一个联通分量上了,不过操作的时候不是f[u]=f[v]这么简略,因为必须使u在的联通分量和v在的联通分量联通起来,所以每个联通分量里的节点的flag值可以指向同一个节点,具体的操作见下面代码:

        

        此题输出边的时候没有要求次序;

        

        参考代码如下:

        

        每日一道理
    时间好比一条小溪,它能招引我们奔向生活的海洋;时间如同一叶扁舟,它将帮助我们驶向理想的彼岸;时间犹如一支画笔,它会指点我们描绘人生的画卷。
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    const int MAX_SIZE=800;
    struct Node
    {
        int u,v;
        double w;
        bool operator < (const Node a)const
        {
            return w<a.w;
        };
    }edge[MAX_SIZE*MAX_SIZE/2];
    struct point
    {
        int x,y;
    }a[MAX_SIZE];
    int flag[MAX_SIZE],num,n,m;
    
    int getflag(int u)
    {
        if(flag[u]!=u)
            flag[u]=getflag(flag[u]);
        return flag[u];
    }
    void execute()
    {
    	int i,j;
    	for(i=1;i<=n;i++)
    	{
    		for(j=i+1;j<=n;j++)
    			if(getflag(i)!=getflag(j))
    			{
    				edge[num].u=i;
    				edge[num].v=j;
    				edge[num++].w=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
    			}
    	}
    	sort(edge,edge+num);
    	for(i=0;i<num;i++)
    		if(getflag(edge[i].u)!=getflag(edge[i].v))
    		{
    			flag[getflag(edge[i].u)]=flag[getflag(edge[i].v)];
    			cout<<edge[i].u<<' '<<edge[i].v<<endl;
    		}
    }
    
    int main()
    {
    	cin>>n;
    	int u,v;
    	int i;
    	for(i=1;i<=n;i++)
    		cin>>a[i].x>>a[i].y;
    	cin>>m;
    	for(i=1;i<=n+2;i++)
    	flag[i]=i;
    	num=0;
    	while(m--)
    	{
    		cin>>u>>v;
    		flag[getflag(u)]=flag[getflag(v)];
    	}
    	execute();
    	return 0;
    }

        

    文章结束给大家分享下程序员的一些笑话语录: Borland说我很有前途,Sun笑了;Sun说我很有钱,IBM笑了;IBM说我很专业,Sybase笑了;Sybase说我数据库很牛,Oracle笑了;Oracle说我是开放的,Linux笑了;Linux说我要打败Unix,微软笑了;微软说我的系统很稳定,我们都笑了。

    --------------------------------- 原创文章 By
    分量和算法
    ---------------------------------

  • 相关阅读:
    HVR数据复制软件部署之(一)--HUB端部署
    LeetCode 169:Majority Element
    [LeetCode][Java] Trapping Rain Water
    跨平台C、C++代码注意的事项
    Delphi通过查找字符定位TADOQuery数据的位置
    ADOquery属性中cursortype,LockType属性
    delphi ADOQuery 开启本地缓存
    如何判断一个事务是否已开始?
    SQL Server 取日期时间部分
    delphi中怎么获取服务器的时间
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3112902.html
Copyright © 2011-2022 走看看