zoukankan      html  css  js  c++  java
  • P1265 公路修建 最小生成树

      

    题目描述

    某国有n个城市,它们互相之间没有公路相通,因此交通十分不便。为解决这一“行路难”的问题,政府决定修建公路。修建公路的任务由各城市共同完成。

    修建工程分若干轮完成。在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路。政府负责审批这些申请以决定是否同意修建。

    政府审批的规则如下:

    (1)如果两个或以上城市申请修建同一条公路,则让它们共同修建;

    (2)如果三个或以上的城市申请修建的公路成环。如下图,A申请修建公路AB,B申请修建公路BC,C申请修建公路CA。则政府将否决其中最短的一条公路的修建申请;

    (3)其他情况的申请一律同意。

    一轮修建结束后,可能会有若干城市可以通过公路直接或间接相连。这些可以互相:连通的城市即组成“城市联盟”。在下一轮修建中,每个“城市联盟”将被看作一个城市,发挥一个城市的作用。

    当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。

    你的任务是根据城市的分布和前面讲到的规则,计算出将要修建的公路总长度。

    输入输出格式

    输入格式:

    第一行一个整数n,表示城市的数量。(n≤5000)

    以下n行,每行两个整数x和y,表示一个城市的坐标。(-1000000≤x,y≤1000000)

    输出格式:

    一个实数,四舍五入保留两位小数,表示公路总长。(保证有惟一解)

    输入输出样例

    输入样例#1: 复制
    4
    0 0
    1 2
    -1 2
    0 4
    输出样例#1: 复制
    6.47


    难点在 第二条规则 但是显然 这条规则是永远不起作用的

    一开始计算所有的距离存在邻接矩阵里面 MLE
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////////
    const int N = 5000+5;
    int f[N];
    int find1(int x)
    {
        return f[x]==x?x:f[x]=find1(f[x]);
    }
    struct node
    {
        int id,id2;
        double x,y;
        double len;
    }s[N],s2[N*N];
    int n,m;
    int cnt=0;
    bool cmp(node a,node b)
    {
        return a.len<b.len;
    }
    int main()
    {
        int b;
        RI(b);
        rep(i,1,b)
        {
            scanf("%lf%lf",&s[i].x,&s[i].y);
            s[i].id=i;
            f[i]=i;
        }
        rep(i,1,b)
        rep(j,1,b)
        if(j>i)
        {
            s2[++cnt].id=s[i].id;
            s2[cnt].id2=s[j].id;
            s2[cnt].len=(double)sqrt( (s[i].x-s[j].x)*(s[i].x-s[j].x)+ (s[i].y-s[j].y)*(s[i].y-s[j].y)  );
        }
        sort(s2+1,s2+1+cnt,cmp);
        int x=1;
        double sum=0;
        rep(i,1,cnt)
        {
            int a1=s2[i].id;
            int b1=s2[i].id2;
            a1=find1(a1);b1=find1(b1);
            if(a1==b1)continue;
            x++;
            f[a1]=b1;
            sum+=s2[i].len;
            if(x==b)
            {
                printf("%.2lf",sum);break;
            }
        }
    }
    View Code

    用的时候直接计算即可

    发现prim算法打起来更加方便

    注意求距离前面要加两个double

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////////
    const int N = 5000+6;
    struct node
    {
        int x,y;
    }s[N];
    double dit(node a,node b)
    {
        return sqrt( (double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y) );
    }
    int vis[N];
    double dis[N];
    int main()
    {
        int n;
        RI(n);
        rep(i,1,n)
        RII(s[i].x,s[i].y),vis[i]=0,dis[i]=1e8;
    
        double ans=0;
        dis[1]=0;int u;
        rep(i,1,n)
        {
            double minn=1e8;
            rep(j,1,n)
            if(!vis[j]&&dis[j]<minn)
            minn=dis[u=j];
            ans+=minn;
            vis[u]=1;
            rep(j,1,n)
            {
                double d=dit(s[j],s[u]);
                if(d<dis[j])dis[j]=d;
            }
        }
        printf("%.2lf",ans);
    }
    View Code






  • 相关阅读:
    golang-cron定时任务
    卡特兰数
    树的直径
    虚拟机之Hyper-V
    tag of loj
    wx.requestSubscribeMessage无法弹窗,显示20001报错?
    nginx日志切割
    小程序首次加载过慢以及点击微信授权不弹出授权框的问题
    外网访问小程序显示网络错误问题以及总是走wx.request里面的fail回调问题
    http转https以及ssl证书配置以及安装
  • 原文地址:https://www.cnblogs.com/bxd123/p/10769934.html
Copyright © 2011-2022 走看看