zoukankan      html  css  js  c++  java
  • POJ 1751 Highways

    最小生成树的水题,直接的最小生成树算法就可以了。题意给定n个城市,只不过是又给定了已经连接起来的道路,由于输出的是城镇的编号,所以不用计算两城镇之间的真正距离(既不用算sqrt),用的是kruskal,比较费时,估计用prim可以节省不少时间.

     

    code
    #include <iostream>
    #include 
    <cstdio>
    #include 
    <cmath>
    #include 
    <algorithm>
    #include 
    <memory.h>
    using namespace std;
    const int MAXN = 800;
    const int MAXE = 500000;
    const int INF = 0x7fffffff;
    int nv,ne,index,set[MAXN],pos[MAXE];
    struct Edge{
        
    int u,v;
        
    int val;
    }edge[MAXE];
    struct Node{
        
    int x,y;
    }node[MAXN];
    int cmp(const Edge& a,const Edge& b)
    {
        
    return a.val < b.val;
    }
    int find_set(int x)
    {
        
    int root = x,tmp;
        
    while(set[root] >= 0)
            root 
    = set[root];
        
    while( x != root)
        {
            tmp 
    = set[x];
            
    set[x] = root;
            x 
    = tmp;
        }
        
    return root;
    }
    void union_set(const int& root1,const int& root2)
    {
        
    int a = set[root1];
        
    int b = set[root1];
        
    if( a>b)
        {
            
    set[root1] = root2;
            
    set[root2] += a;
        }
    else{
            
    set[root2] = root1;
            
    set[root1] += b;
        }
    }
    int kruskal()
    {
        index 
    = 0;
        
    int sum = 0,root1,root2,tmp,i;
        
    for(i = 0;i < ne; ++i)
        {
            root1 
    = find_set(edge[i].u);
            root2 
    = find_set(edge[i].v);
            
    if( root1 != root2)
            {
                pos[index] 
    = i;
                
    ++index;
                union_set(root1,root2);
            }
        }
        
    return sum;
    }
    int main()
    {
        
    int i,j,k,a,b,tmp,val,n,m,root1,root2;
        
    while(scanf("%d",&nv) != EOF)
        {
            memset(
    set,-1,sizeof(set));
            
    for(i = 1;i <= nv; ++i)
                scanf(
    "%d%d",&(node[i]).x,&(node[i].y));
            index 
    = 0;
            
    for(i = 1;i <= nv; ++i)
                
    for(j = i + 1;j <= nv; ++j)
                {
                    edge[index].u 
    = i;
                    edge[index].v 
    = j;
                    edge[index].val 
    = (node[i].x-node[j].x)*(node[i].x-node[j].x)+
                        (node[i].y 
    - node[j].y)*(node[i].y-node[j].y);
                    
    ++index;
                }
            ne 
    = index;
            sort(edge,edge
    +ne,cmp);
            scanf(
    "%d",&n);
            
    for(i = 1;i <= n; ++i)
            {
                scanf(
    "%d%d",&a,&b);
                root1 
    = find_set(a);
                root2 
    = find_set(b);
                
    if( root1 != root2)
                    union_set(root1,root2);
            }
            kruskal();
            
    for(i = 0;i < index; ++i)
                printf(
    "%d %d\n",edge[pos[i]].u,edge[pos[i]].v);
        }
        
    return 0;
    }

     

  • 相关阅读:
    "use strict"详解
    HTML5 文件上传
    jquery $(document).ready() 与window.onload的区别
    前端面试题——错题集
    css-子div设置margin-top影响父div
    常见的dom操作----原生JavaScript与jQuery
    前端面试题——错题集
    JavaScript正则表达式知识点
    越权漏洞
    php反系列化原理和演示
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662729.html
Copyright © 2011-2022 走看看