您的位置:首页 > 其它

POJ2349,ZOJ1914,Arctic Network

2015-07-28 10:09 246 查看
题意就不解释了,需要注意的是,每个卫星频道对应的是一个点,不是一条边!

首先跑完prim之后,会得到一个数组d,里面保存的是最小生成树的每条边

然后有s个卫星频道,那么就有s-1条边,所以直接在d数组里取第s条边就行了(之前得将d数组从大到小排下序)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<cmath>
#include<algorithm>
using namespace std;
int t,s,p;
double maz[509][509];//存图
double d[509];//跑prim时用的数组
bool vis[509];//标记数组
double dis(int a[],int b[])
{
double x,y,sum;
x = (a[0]-b[0]) * (a[0]-b[0]);
y = (a[1]-b[1]) * (a[1]-b[1]);
sum = sqrt((x+y)*1.0);
return sum;
}//得到两点之间的距离
bool cmp(int a,int b)
{
return a > b;
}//使数组元素从大到小排序
void prim()//基本就是模板,只不过这次目的是得到那个d数组,而不是最后结果
{
int i,j,pos,cnt;
double t;
memset(d,false,sizeof(d));
for (i = 1; i <= p; ++i)
d[i] = maz[1][i];
memset(vis,false,sizeof(vis));
vis[1] = true;
for (i = 0; i < p-1; ++i)
{
t = INT_MAX;
for (j = 1; j <= p; ++j)
{
if (!vis[j] && t > d[j])
{
t = d[j];
pos = j;
}
}
vis[pos] = true;
for (j = 1; j <= p; ++j)
{
if (!vis[j] && d[j] > maz[pos][j])
{
d[j] = maz[pos][j];
}
}
}
sort(d+1,d+1+p,cmp);//把数组元素从大到小排序,数组是从1开始的,不是0
cnt = s - 1;
printf("%.2lf\n",d[1+cnt]);//取滴s条边
}
int main()
{
int i,j;
int pi[509][2];
double tem;
while (~scanf("%d",&t))
{
while (t--)
{
scanf("%d%d",&s,&p);
for (i = 1; i <= p; ++i)
{
scanf("%d%d",&pi[i][0],&pi[i][1]);
}//保存原始数据
for (i = 1; i <= p; ++i)
{
for (j = 1; j <= p; ++j)
{
maz[i][j] = i == j ? 0 : INT_MAX;
}
}//初始化maz数组
for (i = 1; i <= p; ++i)
{
for (j = i+1; j <= p; ++j)
{
tem = dis(pi[i],pi[j]);
maz[i][j] = maz[j][i] = tem;
}
}//存图
prim();
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息