POJ-1751-Highways [最小生成树]

来源:互联网 发布:linux libzip 使用 编辑:程序博客网 时间:2024/05/22 01:35

题目传送门


题意:
给定N个城市的坐标,已经建立了M条高速公路,问还需要建立多少条高速公路,才能使所有城市联通,要求建立的高速公路距离总和最短,输出所有新建立的高速公路
思路:
先将已经建立的边合并,用Kruskal求最小生成树,并输出合并的边。

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>#include <queue>#include <map>#include <set>using namespace std;int N;struct node{    int x, y;} point[800];struct node2{    int x, y;    double r;} P[320000];int fa[800];void init(){    for (int i = 1; i <= 800; i++)        fa[i] = i;}bool cmp(node2 a, node2 b){    if (a.r!=b.r)        return a.r < b.r;    else if (a.x!=b.x)        return a.x < b.x;    else        return a.y < b.y;}double Dis(int a, int b){    double px = 1.0*(point[a].x-point[b].x);    double py = 1.0*(point[a].y-point[b].y);    return sqrt(px*px+py*py);}int find(int x){    while (x!=fa[x]) x = fa[x];    return x;}int main(void){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    scanf("%d", &N);    init();    for (int i = 1; i <= N; i++)        scanf("%d %d", &point[i].x, &point[i].y);    int m;    scanf("%d", &m);    while (m--)    {        int x, y;        scanf("%d %d", &x, &y);        x = find(x);        y = find(y);        if (x!=y)        {            fa[x] = y;        }    }    int num = 0;    for (int i = 1; i < N; i++)    {        for (int j = 1+i; j <= N; j++)        {            if (find(i)!=find(j))            {                P[num].x = i;                P[num].y = j;                P[num].r = Dis(i, j);                num++;            }        }    }    sort(P, P+num, cmp);    for(int i = 0; i < num; i++)    {        if (find(P[i].x) != find(P[i].y))        {            int a = find(P[i].x);            int b = find(P[i].y);            fa[a] = b;            printf("%d %d\n", P[i].x, P[i].y);        }    }    return 0;}
原创粉丝点击