Problem E: Communication
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 66 Solved: 11
[Submit][Status][Web Board]
Description
Military training has started. Many groups is training all day. But because NEU has no playground which is big enough to hold all groups, fresh boys and girls have to train in different positions.
For easier command communication, leader decides to set several communicating lines which connect all the groups. Each line connect two groups by straight line. Obviously, it is not need to connect each two groups directly. N groups just need N-1 lines to make all groups connected indirectly.
Your task is, give you N groups' position, you should find N-1 lines that connect all the groups and the total distance of all lines is minimum.
Input
There are several test cases.
In each case, the first line is N, the number of groups. N<=1000. Then N lines, each line has two decimal or integer, which is the ith x-y coordinate.(0<=x,y<=1000).There are no two groups in one same position.
Output
Each case output a line, the minimum sum distance of N-1 lines with exactly two digits after a decimal point.
Sample Input
3 0 0 0 1 0 2 3 0 0 1 1 0 1
Sample Output
2.00 2.00
这道题是一道图论类型的题目,思路很简单就是从一个点出发,每次都从这个最小生成树出发找出距离这可最小生成树最近的点将这些距离累加就是结果注意:思路很简单,可是很容易超时,正常的思路写下去,会是一个O的3次方,很容易出现超时,为了避免超时,做一个数组,用来记录距离,首先从定点0出发,记录剩余的所有点到这个点的所有距离放在这个数组中,然后,每次找到了一个新的节点时,检测剩余的没有被访问过的点到这个新的节点的距离,如果距离有小于数组中已有的记录dis[i],则更新这个距离,也就是说在dis这个数组中记录的永远是剩余的点到这个最小生成树最小的距离,因此在找下一个点时只用做一层循环了每次找出这个数组中剩下的最小的值即是下一个要找的节点,依次类推下去。
#include <iostream>
#include <math.h>
#include <stdio.h>
using
namespace
std;
typedef
struct
{
double
x,y;
bool
value;
}point;
double
getdistance(point a,point b)
{
return
pow
(
pow
(a.x-b.x,2)+
pow
(a.y-b.y,2),0.5);
}
point p[1005];
int
main()
{
int
t,count,index;
double
d,d1,sum,length[1001][1001],distan[1005];
while
(cin>>t)
{
count = 1;
for
(
int
i = 0; i < t; i++)
{
cin>>p[i].x>>p[i].y;
p[i].value =
true
;
}
for
(
int
i=0;i<t;i++)
for
(
int
j=0;j<t;j++)
{
length[i][j] = getdistance(p[i],p[j]);
if
(i==0) distan[j] = length[i][j];
}
p[0].value =
false
;
sum = 0;
index = 0;
while
(count<t)
{
d = 100000000;
for
(
int
j = 0; j < t; j++)
{
if
(p[j].value==
true
&&distan[j]<d)
{
d = distan[j];
index = j;
//cout<<d<<" "<<index<<endl;
}
}
sum += d;
//cout<<index<<endl;
p[index].value =
false
;
count++;
for
(
int
j = 0; j < t; j++)
{
if
(p[j].value==
true
&&length[index][j]<distan[j])
distan[j] = length[index][j];
}
}
printf
(
"%.2f\n"
,sum);
}
return
0;
}
/**************************************************************
Problem: 1115
User: FOT
Language: C++
Result: Accepted
Time:709 ms
Memory:9056 kb
****************************************************************/