zoukankan      html  css  js  c++  java
  • Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)

    题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接。

    思路:两种做法。(1)用prim算法时,输入a,b。令mp[a][b]=0。然后进行一遍prim(2)Kruskal算法+并查集

    代码:

    //prim写法
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #pragma comment (linker,"/STACK:102400000,102400000")
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define FRE(i,a,b)  for(i = a; i <= b; i++)
    #define FREE(i,a,b) for(i = a; i >= b; i--)
    #define FRL(i,a,b)  for(i = a; i < b; i++)
    #define FRLL(i,a,b) for(i = a; i > b; i--)
    #define mem(t, v)   memset ((t) , v, sizeof(t))
    #define sf(n)       scanf("%d", &n)
    #define sff(a,b)    scanf("%d %d", &a, &b)
    #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
    #define pf          printf
    #define DBG         pf("Hi
    ")
    typedef long long ll;
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define mod 1000000009
    const int maxn = 1005;
    const int MAXN = 2005;
    const int MAXM = 200010;
    const int N = 1005;
    
    struct Node
    {
        double x,y;
    }node[maxn];
    
    int n,m;
    double mp[maxn][maxn];
    double dist[maxn];
    bool vis[maxn];
    
    double Dis(Node n1,Node n2)
    {
        return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));
    }
    
    double prim()
    {
        int i,j,now;
        double mi;
        mem(vis,false);
        mem(dist,INF);
        for (i=1;i<=n;i++)
            dist[i]=mp[1][i];
        dist[1]=0;
        vis[1]=true;
        for (i=1;i<=n;i++)
        {
            now=-1;
            mi=INF;
            for (j=1;j<=n;j++)
            {
                if (!vis[j]&&mi>dist[j])
                {
                    now=j;
                    mi=dist[j];
                }
            }
            if (now==-1) break;
            vis[now]=true;
            for (j=1;j<=n;j++)
            {
                if (!vis[j]&&dist[j]>mp[now][j])
                    dist[j]=mp[now][j];
            }
        }
        double ans=0;
        for (i=1;i<=n;i++)
            ans+=dist[i];
        return ans;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
    #endif
        int i,j,u,v;
        while (~sf(n))
        {
            for (i=1;i<=n;i++)
                scanf("%lf%lf",&node[i].x,&node[i].y);
            for (i=1;i<=n;i++)
            {
                for (j=1;j<=n;j++)
                    if (i==j) mp[i][j]=0;
                    else mp[i][j]=Dis(node[i],node[j]);
            }
            sf(m);
            for (i=0;i<m;i++)   //在同一个联通块的距离直接赋为0
            {
                sff(u,v);
                mp[u][v]=mp[v][u]=0;
            }
            printf("%.2f
    ",prim());
        }
        return 0;
    }
    
    
    //Kruskal+并查集写法
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #pragma comment (linker,"/STACK:102400000,102400000")
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define FRE(i,a,b)  for(i = a; i <= b; i++)
    #define FREE(i,a,b) for(i = a; i >= b; i--)
    #define FRL(i,a,b)  for(i = a; i < b; i++)
    #define FRLL(i,a,b) for(i = a; i > b; i--)
    #define mem(t, v)   memset ((t) , v, sizeof(t))
    #define sf(n)       scanf("%d", &n)
    #define sff(a,b)    scanf("%d %d", &a, &b)
    #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
    #define pf          printf
    #define DBG         pf("Hi
    ")
    typedef long long ll;
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define mod 1000000009
    const int maxn = 1005;
    const int MAXN = 1000000;
    const int MAXM = 200010;
    const int N = 1005;
    
    struct Node
    {
        double x,y;
    }node[maxn];
    
    struct Edge
    {
        int u,v;
        double len;
    }edge[MAXN];
    
    int n,m,cnt;
    int father[maxn];
    
    int cmp(Edge e1,Edge e2)
    {
        return e1.len<e2.len;
    }
    
    void init()
    {
        cnt=0;
        for (int i=0;i<=n;i++)
            father[i]=i;
    }
    
    double Dis(Node n1,Node n2)
    {
        return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));
    }
    
    int find_father(int x)
    {
        if (x!=father[x])
            father[x]=find_father(father[x]);
        return father[x];
    }
    
    double Kruskal()
    {
        int i,j;
        double ans=0;
        sort(edge,edge+cnt,cmp);
        for (i=0;i<cnt;i++)
        {
            int fu=find_father(edge[i].u);
            int fv=find_father(edge[i].v);
            if (fu!=fv)
            {
                ans+=edge[i].len;
                father[fu]=fv;
            }
        }
        return ans;
    }
    
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
    #endif
        int i,j,u,v;
        while (~sf(n))
        {
            init();
            for (i=1;i<=n;i++)
                scanf("%lf%lf",&node[i].x,&node[i].y);
            for (i=1;i<n;i++)
            {
                for (j=i+1;j<=n;j++)
                {
                    if (i==j) continue;
                    else
                    {
                        double x=Dis(node[i],node[j]);
                        edge[cnt].u=i;
                        edge[cnt].v=j;
                        edge[cnt++].len=x;
                    }
                }
            }
            sf(m);
            for (i=1;i<=m;i++)
            {
                sff(u,v);
                int fu=find_father(u);
                int fv=find_father(v);
                if (fu!=fv)
                    father[fu]=fv;
            }
            printf("%.2f
    ",Kruskal());
        }
        return 0;
    }


  • 相关阅读:
    Postgresql常用命令&&函数
    gcc g++参数
    cython编译Python为c语言
    安装python3
    pip 国内源
    ceph 对象存储s3
    Rancher基础
    helm常用命令
    chartmuseum配置和使用
    python-etcd3
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7115965.html
Copyright © 2011-2022 走看看