POJ 1751 Highways(最小生成树)

来源:互联网 发布:软件健壮性例子 编辑:程序博客网 时间:2024/05/22 05:09

POJ 1751 Highways(最小生成树)

http://poj.org/problem?id=1751

题意: 

       有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输出需要添加边的两端点编号即可.

分析:

       本题就是求最小生成树的,但是由于本题不需要输出最终生成树的权值,那么我们在求两点距离的时候时间保存距离 dist=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);即可,不用sqrt开方(因为开方费时间).

       然后对于已经连接上的边,我们令他们属于同一个并查集即可(或令这些边长为0,并添加到无向图中去也行)

AC代码:(注意本题要用G++提交,C++提交容易超时)

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=750+10;const int maxm=500000;struct Edge{    int u,v,dist;    Edge(){}    Edge(int u,int v,int d):u(u),v(v),dist(d){}    bool operator<(const Edge &rhs)const    {        return dist < rhs.dist;    }};struct Kruskal{    int n,m;    Edge edges[maxm];    int fa[maxn];    int findset(int x){ return fa[x]==-1? x:fa[x]=findset(fa[x]); }    void init(int n)    {        this->n=n;        m=0;        memset(fa,-1,sizeof(fa));    }    void AddEdge(int u,int v,int dist)    {        edges[m++]=Edge(u,v,dist);    }    int kruskal()    {        int sum=0;        int cnt=0;        sort(edges,edges+m);        for(int i=0;i<m;i++)        {            int u=edges[i].u, v=edges[i].v;            if(findset(u) != findset(v))            {                if(edges[i].dist>0) printf("%d %d\n",u,v);                sum +=edges[i].dist;                fa[findset(u)] = findset(v);                if(++cnt>=n-1) break;            }        }        if(cnt<n-1) return -1;        return sum;    }}KK;struct Point{    int x,y;}p[maxn];int get_dist(int i,int j){    return (p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y);}int main(){    int n,m;    while(scanf("%d",&n)==1)    {        KK.init(n);        for(int i=1;i<=n;i++)            scanf("%d%d",&p[i].x,&p[i].y);        for(int i=1;i<=n;i++)        for(int j=i+1;j<=n;j++)            KK.AddEdge(i,j,get_dist(i,j));        scanf("%d",&m);        for(int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            KK.AddEdge(u,v,0);        }        KK.kruskal();    }    return 0;}


0 0
原创粉丝点击