成大事者,不惟有超世之才,亦有坚忍不拔之志。
秋实大哥开了一家快餐店之后,由于人赢光环的影响,很快就赚得了大量的资金。为了继续实现心中的远大的理想,他打算在全国各地开设分店赚大钱。假设现在有n
家快餐店(其中有至少有一家是旗舰店)分布在二维平面上,第i家快餐店的坐标为(xi, yi
)。为了方便交通,他打算在一些快餐店之间修建道路使得任意一家快餐店都能够通过道路到达某一家旗舰店。
但是秋实大哥忙于赚钱和过节,没有时间来设计道路,你能帮助秋实大哥算出最少一共需要修建多长的道路吗?
Input
第一行一个整数n
,表示快餐店的个数。(n≤6666) 接下来n行,每行两个整数xi,yi,zi(−1000000≤xi,yi≤1000000)。表示第i家快餐店的位置(xi,yi),如果zi=0表示该店是普通的分店,如果 zi=1
表示该店是旗舰店。
保证至少有一家旗舰店
Output
输出最少一共需要修建的道路长度,保留小数点后两位。
样例输入:
3
1 -1 0
1 1 0
0 0 1
样例输出
2.83
题解:
Memory Limit: 65535KB !!!!!!!!
(出现在出题人头上的大棒)
只能写普通prim了
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<cmath>
#define LiangJiaJun main
#define pa pair<double,int>
using namespace std;
const double INF = 2000000.4*2000004.7;
priority_queue<pa,vector<pa>,greater<pa> >q;
int n,z[6674];
double x[6674],y[6674];
double mcs[6674],ans=0;
bool vis[6674];
double dis(double x,double y,double xx,double yy){return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));}
void MST(){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)if(z[i]==1)mcs[i]=0;else mcs[i]=INF;
while(1){
int v = -1;
for(int i=1;i<=n;i++)if(!vis[i]&&(v==-1||mcs[v]>mcs[i]))v=i;
if(v == -1)break;
ans += mcs[v];vis[v]=1;
for(int i=1;i<=n;i++){
double p = dis(x[v],y[v],x[i],y[i]);
if(v!=i&&mcs[i]>p)mcs[i] = p;
}
}
}
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lf%lf%d",&x[i],&y[i],&z[i]);
MST();
printf("%.2lf\n",ans);
return 0;
}