标签:sqrt nod break getchar == for freopen algo ota
roads.in 输出文件:roads.out 简单对比时间限制:1 s 内存限制:128 MB
译 by CmYkRgB123
描述
Farmer John 刚刚得到了几个新农场!他想把这几个农场用路连接起来,这样他就可以通过笔直的公路从一个农场到另一个农场了。现在已经有了几条连接着的农场。
N (1 ≤ N ≤ 1,000) 个农场中,每个农场的位置在坐标平面的 (Xi, Yi) (0 ≤ Xi ≤ 1,000,000; 0 ≤ Yi ≤ 1,000,000)。已经有 M (1 ≤ M ≤ 1,000) 条路以前就被建好了。请你帮助 Farmer John 考虑建设尽量少长度的额外的路,使他的农场连在一起。
输入
* 第 1 行: 两个整数: N , M
* 第 2..N+1 行: 两个整数 Xi , Yi
* 第 N+2..N+M+2 行: 两个整数: i , j, 表示已经存在从农场i到农场j的路。
输出
* 第 1 行: 额外的路的最少长度,保留2小数。 请使用 64 位的浮点数。
样例输入
4 1
1 1
3 1
2 3
4 3
1 4
样例输出
4.00
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1010;
bool vis[N][N];
int fa[N];
int n,m,js,xx,yy,tot,total;
double answer;
struct node{
double x,y;
}E[N];
struct NODE{
int st,ed;
double dis;
}EE[500000];
inline int read()
{
int x=0;char c=getchar();
while(c<‘0‘||c>‘9‘)c=getchar();
while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar();
return x;
}
inline double calc(int a,int b)
{
return sqrt(abs(E[a].x-E[b].x)*abs(E[a].x-E[b].x)+abs(E[a].y-E[b].y)*abs(E[a].y-E[b].y));
}
bool cmp(NODE a,NODE b)
{
return a.dis<b.dis;
}
int getfa(int x)
{
return fa[x]==x?x:fa[x]=getfa(fa[x]);
}
int main()
{
freopen("roads.in","r",stdin);
freopen("roads.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++)
fa[i]=i,scanf("%lf%lf",&E[i].x,&E[i].y);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
EE[++js].st=i,
EE[js].ed=j,
EE[js].dis=calc(i,j);
for(int i=1;i<=m;i++)
xx=read(),
yy=read(),
vis[xx][yy]=vis[yy][xx]=1;
for(int i=1;i<=js;i++)
if(vis[EE[i].st][EE[i].ed])
{
int fx=getfa(EE[i].st);
int fy=getfa(EE[i].ed);
fa[fx]=fy;
EE[i].dis=double(N<<4);
}
tot=n-1-m;
sort(EE+1,EE+js+1,cmp);
for(int i=1;i<=js;i++)
{
int fx=getfa(EE[i].st);
int fy=getfa(EE[i].ed);
if(fx!=fy)
{
fa[fx]=fy;
total++;
answer+=EE[i].dis;
if(total==tot)
break;
}
}
printf("%.2lf",answer);
return 0;
}
标签:sqrt nod break getchar == for freopen algo ota
原文地址:http://www.cnblogs.com/lyqlyq/p/7157722.html