POJ 2349 Arctic Network (最小生成树)

来源:互联网 发布:matlab 二维矩阵画图 编辑:程序博客网 时间:2024/05/17 00:43

题目链接:

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



题意分析:
有P个哨所和S个卫星通道,任意两个哨所的连接可以为(1)用一个卫星通道相连(2)两个哨所的距离小于等于D,求满足任意两个哨所直接或间接相连D的最小值。


解题思路:
题目要求最后任意哨所两两相连,这就转化成最小生成树的问题。
现假设我们已经求得满足要求的最小生成树,以贪心的思维可以想到,每一个卫星通道都应该使用在这个最小生成树里权值最大的边。
由此,题目便转化成求图的最小生成树中第(n-1-s)大的边。用kruskal算法求解。


AC代码(POJ提交时language选择C++):


#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;const int MAXN = 550;const int MAXM = 250050;int T,s,n;int tol;double len[MAXN];int F[MAXN];//并查集使用struct point{    double x,y;}p[MAXN];struct Edge{    int u,v;    double w;    bool operator < (const Edge & e)const    {        return w<e.w;    }}edge[MAXM];void addedge(int u,int v,double w){    edge[tol].u=u;    edge[tol].v=v;    edge[tol++].w=w;}int find(int x){    if(F[x]==-1)return x;    else return F[x]=find(F[x]);}void kruskal(){    memset(F,-1,sizeof(F));    sort(edge,edge+tol);    int cnt=0;    for(int i=0;i<tol;i++)    {        int u=edge[i].u;        int v=edge[i].v;        double w=edge[i].w;        int t1=find(u);        int t2=find(v);        if(t1!=t2)        {            len[cnt]=w;            F[t1]=t2;            cnt++;        }        if(cnt==n-1)break;    }    printf("%.2lf\n",len[n-1-s]);}double dis(int a,int b){    return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));}int main(){    scanf("%d",&T);    while(T--)    {        tol=0;        scanf("%d%d",&s,&n);        for(int i=0;i<n;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        for(int i=0;i<n-1;i++)        {            for(int j=i+1;j<n;j++)            {                double distance = dis(i,j);                addedge(i,j,distance);            }        }        kruskal();    }    return 0;}


原创粉丝点击