HDU 4463 Outlets (最小生成树kruskal算法)

Outlets

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
In China, foreign brand commodities are often much more expensive than abroad. The main reason is that we Chinese people tend to think foreign things are better and we are willing to pay much for them. The typical example is, on the United Airline flight, they give you Haagendazs ice cream for free, but in China, you will pay $10 to buy just a little cup.
So when we Chinese go abroad, one of our most favorite activities is shopping in outlets. Some people buy tens of famous brand shoes and bags one time. In Las Vegas, the existing outlets can’t match the demand of Chinese. So they want to build a new outlets in the desert. The new outlets consists of many stores. All stores are connected by roads. They want to minimize the total road length. The owner of the outlets just hired a data mining expert, and the expert told him that Nike store and Apple store must be directly connected by a road. Now please help him figure out how to minimize the total road length under this condition. A store can be considered as a point and a road is a line segment connecting two stores.

Input
There are several test cases. For each test case: The first line is an integer N( 3 <= N <= 50) , meaning there are N stores in the outlets. These N stores are numbered from 1 to N. The second line contains two integers p and q, indicating that the No. p store is a Nike store and the No. q store is an Apple store. Then N lines follow. The i-th line describes the position of the i-th store. The store position is represented by two integers x,y( -100<= x,y <= 100) , meaning that the coordinate of the store is (x,y). These N stores are all located at different place. The input ends by N = 0.

Output
For each test case, print the minimum total road length. The result should be rounded to 2 digits after decimal point.

Sample Input

4
2 3
0 0
1 0
0 -1 
1 -1
0

Sample Output

3.41

Source
2012 Asia Hangzhou Regional Contest
题目网址: http://acm.hdu.edu.cn/showproblem.php?pid=4463
翻译:
问题描述
在中国,外国品牌商品往往比国外贵得多。主要原因是我们中国人倾向于认为外国的东西更好,我们愿意为他们付出很多。典型的例子是,在美国联合航空公司的航班上,他们免费为您提供Haagendazs冰淇淋,但在中国,您只需花10美元购买一小杯。
因此,当我们中国人出国时,我们最喜欢的活动之一就是在商店购物。有些人一次买几十个名牌鞋包。在拉斯维加斯,现有的网点无法满足中国人的需求。所以他们想在沙漠中建立一个新的网点。新的商店包括许多商店。所有商店都通过道路连接。他们希望尽量减少道路总长度。这些网点的所有者刚刚聘请了一位数据挖掘专家,而专家告诉他,耐克商店和Apple商店必须通过一条道路直接连接。现在请帮助他弄清楚在这种情况下如何最小化道路总长度。商店可以被视为一个点,道路是连接两个商店的线段。

输入
有几个测试用例。对于每个测试用例:第一行是整数N(3 <= N <= 50),这意味着出口中有N个存储。这些N个商店的编号从1到N.第二行包含两个整数p和q,表示No.p商店是Nike商店,而q商店是Apple商店。然后是N行。第i行描述了第i个商店的位置。商店位置由两个整数x,y(-100 <= x,y <= 100)表示,这意味着商店的坐标是(x,y)。这N家商店都位于不同的地方。输入以N = 0结束。

输出
对于每个测试用例,打印最小总道路长度。结果应舍入为小数点后的2位数。

样本输入

4
2 3
0 0
1 0
0 -1 
1 -1
0

样本输出

3.41

资源
2012年亚洲杭州区域竞赛
题意: 本题要求在一条路固定的情况下,把所有的商店连到一块,求出最小道路长度。
思路: 本题是个典型的最小生成树问题,不过有所不同的是有一条路是固定的,可以先把这条路的长度先赋给sum,并把这条路的长度变为0
代码:

#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int f[51];
struct line
{
    int u;
    int v;
    double w;
}lines[1250];   //结构体数量不要小了
int cmp(const void *a,const void *b)	//快排的从小到大的排序函数
{
    return (*(line *)a).w>(*(line *)b).w?1:-1;
}
void init(int n)	//初始化
{
    for(int i=1;i<=n;i++) f[i]=i;
}
int getf(int a)	//找亲戚
{
    if(f[a]==a) return a;
    else
    {
        f[a]=getf(f[a]);
        return f[a];
    }
}
int  merge(int a,int b)	//判断是否在一个集合里
{
    int t1,t2;
    t1=getf(a);
    t2=getf(b);
    if(t1!=t2)	//没在一个集合里合在一起并返回1
    {
        f[t2]=t1;
        return 1;
    }
    else return 0;
}
int main(int argc, const char * argv[])
{
    double w;
    int x[51],y[51];
    int n,p,q,t,k;
    double sum;
    while(cin>>n)
    {
        if(n==0)
            break;
        init(n);    //初始化
        t=0;
        sum=0.0;
        scanf("%d %d",&p,&q);
        if(p>q) //p为小的
        {
            k=p;p=q;q=k;
        }
        for(int i=1;i<=n;i++)   //输入坐标
        {
            scanf("%d %d",&x[i],&y[i]);
        }
        for(int h=1;h<=n;h++)
        {
            for(int l=1;l<h;l++)
            {
                w=sqrt(1.0*(x[h]-x[l])*(x[h]-x[l])+1.0*(y[h]-y[l])*(y[h]-y[l]));    //求两点的距离
                if(h==q&&l==p)  //判断是否为指定的路
                {
                    sum=w;
                    w=0.0;
                }
                lines[t].u=h;
                lines[t].v=l;
                lines[t].w=w;
                t++;
            }
        }
        qsort(lines,t,sizeof(lines[0]),cmp);	//快排
        for(int i=0;i<=t-1;i++)
        {
            if(merge(lines[i].u,lines[i].v)==1)	//组合的最小生成树所需的路
            {
                sum+=lines[i].w;
            }
        }
        printf("%.2lf\n",sum);
    }
    return 0;
}



运行结果:
在这里插入图片描述
总结: 本题就是个典型的最小生成树的题,对我们学习最小生成树有很大的帮助,学习算法不只是要了解它的原理,还要用到实践上。
最小生成树总结: (https://blog.csdn.net/qq_41657977/article/details/84976989)
杭电oj题目分类

猜你喜欢

转载自blog.csdn.net/qq_41657977/article/details/88089622
今日推荐