uva 10397 Connect the Campus 把学校连起来

原题:
any new buildings are under construction on the campus of the University of Waterloo. The university
has hired bricklayers, electricians, plumbers, and a computer programmer. A computer programmer?
Yes, you have been hired to ensure that each building is connected to every other building (directly or
indirectly) through the campus network of communication cables.
We will treat each building as a point speci ed by an x-coordinate and a y-coordinate. Each
communication cable connects exactly two buildings, following a straight line between the buildings.
Information travels along a cable in both directions. Cables can freely cross each other, but they are
only connected together at their endpoints (at buildings).
You have been given a campus map which shows the locations of all buildings and existing commu-
nication cables. You must not alter the existing cables. Determine where to install new communication
cables so that all buildings are connected. Of course, the university wants you to minimize the amount
of new cable that you use.
Input
The input le describes several test cases. The description of each test case is given below:
The rst line of each test case contains the number of buildings
N
(1

N

750). The buildings
are labeled from 1 to
N
. The next
N
lines give the
x
and
y
coordinates of the buildings. These
coordinates are integers with absolute values at most 10000. No two buildings occupy the same point.
After that there is a line containing the number of existing cables
M
(0

M

1000) followed by
M
lines describing the existing cables. Each cable is represented by two integers: the building numbers
which are directly connected by the cable. There is at most one cable directly connecting each pair of
buildings.
Output
For each set of input, output in a single line the total length of the new cables that you plan to use
rounded to two decimal places.
SampleInput
4
103 104
104 100
104 103
100 100
1
4 2
4
103 104
104 100
104 103
100 100
1
4 2
SampleOutput
4.41
4.41
题目大意:
滑铁卢大学很吊,有很多楼。现在校长想用电缆让所有学校连通。当然,电缆是又价格的,现在给你一堆点代表楼的位置,然后再给你一个数,告诉你有多少个楼已经连好电缆不用你连了,问你让所有学校连通需要多长电缆。
思路见代码下方

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
#include <iomanip>
using namespace std;
int father[751];
int rank[751];
int es;//边数
void ini(int n)
{
    for(int i=1;i<=n;i++)
    {
        father[i]=i;
        rank[i]=0;
    }
}
int Find(int x)
{
    if(father[x]==x)
    return x;
    else
    return father[x]=Find(father[x]);
}
bool merge(int a,int b)
{
    int x=Find(a);
    int y=Find(b);
    if(x==y)
    return false;
    if(rank[x]<rank[y])
    father[x]=y;
    else
    {
        father[y]=x;
        if(rank[x]==rank[y])
        rank[x]++;
    }
    return true;
}
struct point
{
    double x,y;
};
double dis(const point &a,const point &b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct edge
{
    int from,to;
    double cost;
};
edge e[562500];
bool cmp(const edge &e1,const edge &e2)
{
    return e1.cost<e2.cost;
}
double kruskal()
{
    double res=0;
    for(int i=1;i<=es;i++)
    {
        edge ee=e[i];
        if(merge(ee.from,ee.to))
        res+=ee.cost;
    }
    return res;
}
point p[751];
bool cab[751][751];
int main()
{
    ios::sync_with_stdio(false);
    int n,a,b,t;
    double ans;
    while(cin>>n)
    {
        memset(cab,false,sizeof(cab));
        ini(n);
        es=1;
        for(int i=1;i<=n;i++)
        cin>>p[i].x>>p[i].y;
        cin>>t;
        for(int i=1;i<=t;i++)
        {
            cin>>a>>b;
            cab[a][b]=true;
            cab[b][a]=true;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<i;j++)
            {
                e[es].from=i;
                e[es].to=j;
                if(cab[i][j])
                e[es].cost=0;
                else
                e[es].cost=dis(p[i],p[j]);
                es++;
            }
        }
        sort(e+1,e+1+es,cmp);
        ans=kruskal();
        cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<endl;
    }
    return 0;
}




思路:
裸的最小生成树,先把给你的连好电缆的节点之间的距离设置成0,然后用克鲁斯卡尔算法就好

你可能感兴趣的:(uva 10397 Connect the Campus 把学校连起来)