4 2 3 0 0 1 0 0 -1 1 -1 0
3.41
题意:
有n家店,要你把他们连在一起(即建成一颗最小生成树),q,p是要求必须有边直接连的,然后就给你n个店的坐标。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#define N 110
#define Mod 10000007
#define lson l,mid,idx<<1
#define rson mid+1,r,idx<<1|1
#define lc idx<<1
#define rc idx<<1|1
const double EPS = 1e-11;
const double PI = acos ( -1.0 );
typedef long long ll;
const int INF = 1000010;
using namespace std;
int n;
int A,B;
int par[N],R[N];
double X[N],Y[N];
struct edge {
int u,v;
double cost;
};
edge es[N*N];
int E;
void init() {
for(int i=0; i<=n; i++) {
par[i]=i;
R[i]=0;
}
}
int finds(int x) {
if(par[x]==x)return x;
return par[x]=finds(par[x]);
}
void unite(int x,int y) {
x=finds(x);
y=finds(y);
if(x==y)return;
if(R[x]<R[y])par[x]=y;
else {
par[y]=x;
if(R[x]==R[y])R[x]++;
}
}
bool same(int x,int y) {
return finds(x)==finds(y);
}
double dis(int i,int j) {
return sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
}
bool cmp(edge a,edge b) {
return a.cost<b.cost;
}
void kruscal() {
double ans=dis(A,B);
unite(A,B);
for(int i=0; i<E; i++) {
edge e=es[i];
if(!same(e.u,e.v)) {
ans+=e.cost;
unite(e.u,e.v);
}
}
printf("%.2f\n",ans);
}
int main() {
while(cin>>n&&n) {
cin>>A>>B;
for(int i=1; i<=n; i++)
cin>>X[i]>>Y[i];
E=0;
for(int i=1; i<=n; i++) {
for(int j=i+1; j<=n; j++) {
es[E].u=i;
es[E].v=j;
es[E++].cost=dis(i,j);
}
}
init();
sort(es,es+E,cmp);
kruscal();
}
return 0;
}
原文:http://blog.csdn.net/acm_baihuzi/article/details/44550681