zoukankan      html  css  js  c++  java
  • HDU1875 畅通工程再续【最小生成树】

    题意:

    在这些小岛中建设最小花费的桥,但是一座桥的距离必须在10 -- 1000之间。

    思路:

    用最小生成树解决吧,就那两个算法。

    代码:

    prim

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    
    using namespace std;
    #define N 105
    #define inf 0x3f3f3f3f
    
    int n,i,j,x[N],y[N];
    double map[N][N];
    bool vis[N];//标记是否已经放入最小生成树的那个集合里了
    double low[N];//记录不在已经加入最小生成树的这个集合里的元素到这个 集合的最小距离
    
    double dis(int i,int j)
    {
        return sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
    }
    
    void init()
    {
        for(i=1;i<=n;++i)
            cin>>x[i]>>y[i];
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
            {
                map[i][j]=dis(i,j);
                if(map[i][j]>1000||map[i][j]<10)
                {
                    map[i][j]=inf;
                }
            }
    }
    
    void prim()
    {
        double sum=0;
        memset(vis,0,sizeof(vis));
        int pos=1;//从1开始
        for(i=1;i<=n;++i)//第一次给low赋值
        {
            low[i]=map[1][i];
        }
        vis[1]=1;
        //已经找到一个点1,再找n-1个
        for(i=1;i<n;++i)
        {
            double min=inf;
            for(j=1;j<=n;++j)
            {
                if(!vis[j]&&min>low[j])//找下一个点到这个集合的最小值
                {
                    min=low[j];//记下这个最小值
                    pos=j;//记下这个点
                }
            }
            if(min==inf)
            {
                cout<<"oh!"<<endl;
                return ;
            }
            sum+=min;
            vis[pos]=1;//把刚刚找到的这个点加入集合
            for(j=1;j<=n;++j) //更新low数组
            {
                if(!vis[j]&&low[j]>map[pos][j])
                {
                    low[j]=map[pos][j];
                }
            }
        }
        printf("%.1lf
    ",sum*100);
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            init();
            prim();
        }
        return 0;
    }
    View Code

    kruskal

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct Island
    {
        int x,y;
    };
    struct node 
    {
        int u,v;
        double w;
    };
    Island arr[220];
    node  edge[20000];
    int per[220];
    int n;
    bool cmp(node a,node b)
    {
        return a.w<b.w;
    }
    void init()
    {
        for(int i=1;i<=n;++i)
        {
            per[i]=i;
        }
    }
    int find(int x)
    {
        if(x==per[x]) return x;
        return per[x]=find(per[x]);
    }
    bool join(int x,int y)
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
        {
            per[fx]=fy;
            return 1;
        } 
        return 0;
    }
    int main()
    {
        int T;
        int i,j,k;
        double x,y;
        scanf("%d",&T);
        while(T--)
        {
            
            scanf("%d",&n);
            init();
            for(i=1;i<=n;++i)
            {
                scanf("%d%d",&arr[i].x,&arr[i].y);                        
            }
            //m=n*(n-1)/2;
            k=0;
            for(i=1;i<=n;++i)//把所有路记录在node结构体中
            {
                for(j=i+1;j<=n;++j)
                {
                    edge[k].u=i;
                    edge[k].v=j;
                    x=(arr[j].y-arr[i].y)*(arr[j].y-arr[i].y);
                    y=(arr[j].x-arr[i].x)*(arr[j].x-arr[i].x);
                    double temp=sqrt(x+y);
                    edge[k++].w=temp;
                }
            }        
            sort(edge,edge+k,cmp);
            double sum=0;
            for(i=0;i<k;++i)
            {
                if(edge[i].w<=1000&&edge[i].w>=10&&join(edge[i].u,edge[i].v))//如果两个岛的距离不符合要求就会把join(edge[i].u,edge[i].v)短路
                {
                    sum+=edge[i].w;
                }
            }
            int cnt=0;
            bool flag=0;
            for(i=1;i<=n;++i)//短路了就不会执行了,也就不会连接了,就只需要判断根节点的个数
            {
                if(i==per[i]) cnt++;
                if(cnt>1) //不等于1就还有元素(小岛)没连起来,不满足题意
                {
                    flag=1;
                    break;
                }
            }
            if(flag) printf("oh!
    ");
            else
                printf("%.1lf
    ",sum*100);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    论文摘录 Where are the Semantics in the Semantic Web?
    (论文摘录) Semantic Web Services
    Visual C++ Walkthrough: Creating a Windows Forms Control
    (摘录)(ASWP chap3)Describing Web Resource in RDF
    XML Design (A Gentle Transition from XML to RDF)(一个很好的关于RDF的slides)
    论文阅读 Sesame: A Generic Architecture for Storing and Querying RDF and RDF Schema
    Difference between Logic Layer and Proof Layer
    RDF Basics
    WS中Orchestration和Choreography的含意
    摘录) (ASWP) Chap 5 Logic & Inference: rules
  • 原文地址:https://www.cnblogs.com/darklights/p/7647843.html
Copyright © 2011-2022 走看看