The first line contains 0 < n <= 100, the number of freckles on Dick's back. For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle.
Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles.
3 1.0 1.0 2.0 2.0 2.0 4.0
3.41
#include<iostream> (720)#include<sstream> #include<algorithm> (831)#include<queue> #include<cmath> (808)#include<string> #include<cstdio> (802)#include<regex> #include<vector> (721)#include<stack> #include<bitset> (1494)#include<iomanip> #include<stdlib.h> (794)#include<map> using namespace std; const int N = 200; struct Edge { int start; int end; double length; //int builded; bool operator < (Edge c) const { return length < c.length; } }; struct point { double x; double y; }; int father[N]; int height[N]; void Initial() { for (int i = 0; i < N; i++) { father[i] = i; height[i] = 0; } } int Find(int x) //寻找根节点 { if (x != father[x]) { father[x] = Find(father[x]); } return father[x]; } void Union(int x,int y) { x = Find(x); y = Find(y); if (x != y) { if (height[x] > height[y]) { father[y] = x; } else if (height[x] < height[y]) father[x] = y; else { father[y] = x; height[x]++; //二者高度相同时,其中一个加1 } } } double Kruskal(vector<Edge>edge) { double count = 0; sort(edge.begin(), edge.end()); //sort(unedge.begin(), unedge.end()); for (int i = 0; i < edge.size(); i++) { if (Find(edge[i].start) != Find(edge[i].end)) { Union(edge[i].start, edge[i].end); count = count+edge[i].length; } } /*for (int i = 0; i < unedge.size(); i++) { if (Find(unedge[i].start) != Find(unedge[i].end)) { Union(unedge[i].start, unedge[i].end); count += unedge[i].length; } } */ return count; } double distance(double x1, double y1, double x2,double y2) { return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } int main() { int n; while (cin >> n) { Initial(); vector<point> points; vector<Edge> edges; for (int i = 0; i < n; i++) { point a; cin >> a.x >> a.y; points.push_back(a); } for(int i=0;i<points.size();i++) for (int j = i + 1; j<points.size()&&j > i; j++) { Edge s; s.start = i; s.end = j; s.length = distance(points[i].x, points[i].y, points[j].x, points[j].y); edges.push_back(s); } cout <<fixed<<setprecision(2)<< Kruskal(edges) << endl; } }
#include<iostream> #include<cmath> using namespace std; struct Point//定义点集 { double x; double y; }; int main() { Point point[500]; int n;//点的个数 int cnt = 0;//已访问的点个数 double minSum = 0;//最小的距离和 double mapInfo[500][500];//用于储存点集距离信息 double distanceToTree[500];//到最小生成树的距离信息 cin >> n;//输入点的信息 for (int i = 1; i <= n; i++) { cin >> point[i].x >> point[i].y; } for (int i = 1; i <= n; i++)//计算点与点之间的距离信息 { for (int j = i; j <= n; j++) { if (i == j) mapInfo[i][j] = mapInfo[j][i] = 0; else mapInfo[i][j] = mapInfo[j][i] = sqrt((point[i].x - point[j].x)*(point[i].x - point[j].x) + (point[i].y - point[j].y)*(point[i].y - point[j].y)); } } //初始化到最小生成数的信息,假设从点 1 开始 for (int i = 1; i <= n; i++) distanceToTree[i] = mapInfo[1][i]; cnt = 1;//将点 1 放入树中 while (cnt < n) { int temp_n;//局部变量用于存放即将连接的点 double minDistance = 9999999;//局部变量用于存放到生成树的最小距离,即distanceToTree中的最小非零值 for (int i = 1; i <= n; i++) { if (distanceToTree[i] != 0 && minDistance > distanceToTree[i]) { minDistance = distanceToTree[i]; temp_n = i; } } //将temp_n这个点放入树中 cnt++; minSum += minDistance;//添加距离 distanceToTree[temp_n] = 0;//由于temp_n已在树中,所以将它到树的距离置零,防止重复访问 for (int i = 1; i <= n; i++)//将各个点到temp_n的距离,与各个点到树的距离进行比较(因为此时temp_n已经在树中),更新到树的距离 { if (distanceToTree[i] > mapInfo[temp_n][i]) distanceToTree[i] = mapInfo[temp_n][i]; } } printf("%.2lf\n", minSum); return 0; }
#include<stdio.h> #include<algorithm> #include<math.h> #define N 101 using std::sort; using std::sqrt; int T[N]; int find(int x) { if (T[x] == -1)return x; else { int tmp = find(T[x]); T[x] = tmp; return tmp; } }//寻找根节点 struct Edge { int a, b; double cost; bool operator<(const Edge &A)const { return cost < A.cost; } }edge[500000];//边节点,重载<号 struct Point { double x, y; double distance(const Point &t)const { double tmp = (t.x - x)*(t.x - x) + (t.y - y)*(t.y - y); return sqrt(tmp); } }point[1010]; int main() { int n; while (scanf("%d", &n) != EOF && n != 0) { for (int i = 1; i <= n; i++) T[i] = -1;//初始化树 for (int i = 1; i <= n; i++) { scanf("%lf%lf", &point[i].x, &point[i].y); }//输入点 int edgesize = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { edge[edgesize].a = i; edge[edgesize].b = j; edge[edgesize].cost = point[i].distance(point[j]); edgesize++; } }//输入边 sort(edge, edge + edgesize);//对边排序 double ans = 0; for (int i = 0; i <edgesize ; i++) { int a = find(edge[i].a); int b = find(edge[i].b); if (a != b) { ans += edge[i].cost; T[a] = b; } } printf("%.2lf\n", ans); } return 0; }
#include<bits/stdc++.h> using namespace std; /*并查集+KrusKal算法*/ struct Point { double x; double y; }; struct Edge { //用编号代替点 int from; int to; double length; bool operator<(const Edge&e)const{ return length<e.length; } }; const int MAXN=101; Edge edge[MAXN*MAXN];//边集 Point point[MAXN];//点集 int father[MAXN]; int height[MAXN]; void InitialF(int n)//初始化 { for(int i=0;i<n;i++) { father[i]=i; height[i]=0; } } void Initial(int n) {//构建边集,计算i到j的距离平方 int count=0; for(int i=0;i<n;i++) { double length; for(int j=i+1;j<n;j++) { length=(point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y); edge[count].from=i; edge[count].to=j; edge[count++].length=length; } } } int Find(int x)//压缩路径 { if(x!=father[x]) father[x]=Find(father[x]); return father[x]; } void Union(int x,int y)//矮树挂高树 { x=Find(x); y=Find(y); if(x!=y) { if(height[x]>height[y]) father[y]=x; else if(height[y]>height[x]) father[x]=y; else{ father[y]=x; height[x]++; } } return ; } double KrusKal(int n,int edgeNumber) { InitialF(n); sort(edge, edge+edgeNumber);//从小到大排序 double answer=0; for(int i=0;i<edgeNumber;i++) { if(Find(edge[i].from)!=Find(edge[i].to)) { Union(edge[i].from, edge[i].to); answer+=sqrt(edge[i].length); } } return answer; } int main() { int n; while(cin>>n) { int edgeNumber=n*(n-1)/2; for(int i=0;i<n;i++) cin>>point[i].x>>point[i].y; Initial(n); printf("%.2f\n",KrusKal(n, edgeNumber)); } return 0; }
#include <iostream> #include <set> #include <algorithm> using namespace std; class Dot { public: double x{}; double y{}; double getDistance(Dot other) { return sqrt(pow(x - other.x, 2) + pow(y - other.y, 2)); } Dot(double x, double y) :x(x), y(y) {}; Dot() = default; bool operator < (const Dot& p) const { if (this->x < p.x) { return true; } else if (this->x > p.x) { return false; } else if (this->y < p.y) { return true; } else { return false; } } }; void prim(set<Dot> U, set<Dot> V) { double sum = 0; Dot tmp; while (!V.empty()) { double mmin = 0xffff; for (auto u : U) { for (auto v : V) { double distance = u.getDistance(v); if (distance < mmin) { mmin = min(mmin, distance); tmp = v; } } } U.insert(tmp); V.erase(tmp); sum += mmin; } printf("%.2lf\n", sum); } int main() { int n; while (cin >> n) { double x, y; set<Dot> U, V; cin >> x >> y; U.insert(Dot(x, y)); for (int i = 1; i <= n - 1; i++) { cin >> x >> y; V.insert(Dot(x, y)); } prim(U, V); } return 0; }
#include<iostream> #include<vector> #include<map> #include<algorithm> #include<cmath> using namespace std; struct point { int index; double x, y; point(int i, double a, double b) :index(i), x(a), y(b) {} }; struct edge { int start, end; double dis; edge(int s, int e, double d) :start(s), end(e), dis(d) {} }; double distance(point p1, point p2) { double a = abs(p1.x - p2.x); double b = abs(p1.y - p2.y); return sqrt(a * a + b * b); } int find_root(map<int, int>& V, int x) { if (V.find(x) != V.end() && x != V[x]) V[x] = find_root(V, V[x]); else return x; return V[x]; } double kruskal(vector<edge>& E, int n) { double cost = 0, count = 0; map<int, int> V; vector<edge>::iterator it = E.begin(); while (count != n -1) { while (it != E.end()) { int a = find_root(V,it->start); int b = find_root(V,it->end); if (a != b) { V[b] = a; cost += it->dis; it++; break; } else it++; } count++; } return cost; } bool comp(edge e1, edge e2) { return e1.dis < e2.dis; } int main() { int n; vector<point> P; vector<point>::iterator it; vector<edge> E; while (cin>>n) { for (int i = 0; i < n; i++) { double x, y; cin >> x >> y; point temp(i + 1, x, y); it = P.begin(); while (it != P.end()) { E.push_back(edge(it->index, temp.index, distance(*it, temp))); it++; } P.push_back(temp); } sort(E.begin(), E.end(), comp); cout.precision(2); cout<< fixed << kruskal(E, n) << endl; P.clear(); E.clear(); } return 0; }
#include <bits/stdc++.h> using namespace std; const int maxv = 105; typedef pair<double, double> pdd; vector<pdd> point; const double INF = 1100000000.0; double getDis(pdd &a, pdd &b) { return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second)); } struct edge { int to; double len; edge(int a, double b) : to(a), len(b) {} }; struct node { int v; double d; node(int a, double b) : v(a), d(b) {} bool operator < (const node &a) const { return d > a.d; } }; vector<edge> g[maxv]; double dis[maxv]; bool vis[maxv]; priority_queue<node> q; double Prim(int n) { fill(dis, dis + n, INF); memset(vis, 0, sizeof(vis)); dis[0] = 0; while(!q.empty()) q.pop(); q.push(node(0, dis[0])); double ans = 0; while(!q.empty()) { int u = q.top().v; q.pop(); if(vis[u]) continue; vis[u] = 1; ans += dis[u]; for(int i = 0; i < g[u].size(); ++i) { int v = g[u][i].to; double d = g[u][i].len; if(d < dis[v]) { dis[v] = d; q.push(node(v, dis[v])); } } } return ans; } int main() { int n; while(~scanf("%d", &n)) { double x, y; point.clear(); for(int i = 0; i < n; ++i) { scanf("%lf%lf", &x, &y); point.push_back(pdd(x, y)); } for(int i = 0; i < n - 1; ++i) { for(int j = i + 1; j < n; ++j) { double distance = getDis(point[i], point[j]); g[i].push_back(edge(j, distance)); g[j].push_back(edge(i, distance)); } } printf("%.2f\n", Prim(n)); } return 0; }基本属于裸的最小生成树,为了增加难度用带堆优化的Prim实现了一遍
#include<iostream> (720)#include<string> #include<string.h> (845)#include<vector> #include<algorithm> (831)#include<queue> #include<cstdio> (802)#include<set> using namespace std; #define MAX 105 (5434)#define ll int #define inf 100000000 (5431)#define vec vector<ll> struct P { double x, y; }points[MAX]; struct edge { ll from, to; double dist; edge(ll f = 0, ll t = 0, double d = 0) { from = f, to = t, dist = d; } }; bool cmp(edge e1, edge e2) { return e1.dist < e2.dist; } double d(P p1, P p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); } ll n, kind[MAX], cnt; double a, b, res = 0; ll find(ll k) { if (kind[k] == k)return k; else return kind[k] = find(kind[k]); } void unite(ll a, ll b) { kind[find(b)] = kind[find(a)]; } int main() { while (cin >> n) { vector<edge> v; res = 0; cnt = 0; for (int i = 0; i < n; i++)kind[i] = i; for (int i = 0; i < n; i++) cin >> points[i].x >> points[i].y; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { double dis = d(points[i], points[j]); v.push_back(edge(i, j, dis)); } } sort(v.begin(), v.end(), cmp); for (int i = 0; i < v.size() && cnt < n - 1; i++) { edge e = v[i]; if (find(e.from) == find(e.to))continue; unite(e.from, e.to); res += e.dist; cnt++; } printf("%.2f", res); } }
#include<cstdio> (802)#include<vector> #include<cmath> using namespace std; const int maxn = 105; const double inf = 0x7fffffff; double d[maxn]; int n; bool vis[maxn]; struct Point { double x, y; int id; }; vector<Point> pv; double g[maxn][maxn]; double prim(int st) { fill(d, d + maxn, inf); d[st] = 0; double ans = 0; for (int i = 0; i < n; ++i) { double minD = inf; int u = -1; for (int v = 0; v < n; ++v) { if (!vis[v] && d[v] < minD) { minD = d[v]; u = v; } } if (u == -1) { return -1; } else { vis[u] = true; ans += d[u]; for (int v = 0; v < n; ++v) { if (!vis[v] && g[u][v] != inf && g[u][v] < d[v]) { d[v] = g[u][v]; } } } } return ans; } double getDist(Point a, Point b) { double tmp = pow(a.x - b.x, 2) + pow(a.y - b.y, 2); return sqrt(tmp); } int main() { scanf("%d", &n); double x, y; for (int i = 0; i < n; ++i) { scanf("%lf %lf", &x, &y); pv.push_back(Point{x, y, i}); } for (int i = 0; i < pv.size(); ++i) { for (int j = i; j < pv.size(); ++j) { int a = pv[i].id; int b = pv[j].id; if (a == b) { g[a][b] = inf; } else { g[b][a] = g[a][b] = getDist(pv[i], pv[j]); } } } double ans = prim(0); printf("%.2lf", ans); return 0; }
#define _CRT_SECURE_NO_WARNINGS (842)#include <iostream> #include <cstdio> (802)#include <algorithm> #include <vector> (721)#include <cmath> using namespace std; //Kruskal算法 const int MAXN = 110; struct Point { float x,y; }point[MAXN]; float getDistance(Point from, Point to); struct Edge { int from; int to; float distance; Edge(int f, int t) :from(f), to(t), distance(getDistance(point[f], point[t])) {} bool operator<(Edge& e)const { return distance < e.distance; } }; vector<Edge> edge; int father[MAXN]; int height[MAXN]; float getDistance(Point from, Point to) { return sqrt(pow(from.x - to.x, 2) + pow(from.y - to.y, 2)); } void Initial(int vexNum) { for (int i = 0; i <= vexNum; i++) { father[i] = i; height[i] = 0; } } int Find(int p) { if (father[p]!=p) { p = Find(father[p]); } return p; } void Union(int x, int y) { x = Find(x); y = Find(y); if (x != y) { if (height[x] < height[y]) { father[x] = y; } else if (height[x] > height[y]) { father[y] = x; } else { father[y] = x; height[x]++; } } } float Kruskal(int vexNum, int edgeNum) { Initial(vexNum); sort(edge.begin(), edge.end()); float total = 0; for (int i = 0; i < edge.size(); i++) { Edge cur = edge[i]; if (Find(cur.from) != Find(cur.to)) { total += cur.distance; Union(cur.from, cur.to); } } return total; } int main() { int n; while (scanf("%d", &n) != EOF) { edge.clear(); for (int i = 0; i < n; i++) { scanf("%f%f", &point[i].x, &point[i].y); } int edgeNum = n * (n - 1) / 2; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { edge.push_back(Edge(i, j)); } } float total=Kruskal(n, edgeNum); printf("%.2f\n", total); } return 0; }
#include <stdio.h> #include <math.h> #include <stdlib.h> struct edge { int s; //起点source int d; //终点destination float dis; }e[5000]; //100个点,最多只有(100*99)/2条边,大概5000条左右 int root[101]; int cmp(struct edge *a,struct edge *b) { return (int)((a->dis)*100-(b->dis)*100); //float型数据变量相减再转换回int会有误差,乘以100倍放大误差 } //并且如果用 return a->dis>b->dis 会出错 int find(int x) { int k=x,temp; while(x!=root[x])x=root[x]; while(k!=root[k]) //不用递归的路径压缩,大大降低树的高度 { temp=root[k]; root[k]=x; k=temp; } return x; } void join(int x,int y) { int p=find(x),q=find(y); if(p!=q)root[q]=p; } float kruskal(int n,int nedge) //n为结点的个数,nedge为边条数 { qsort(e,nedge,sizeof(struct edge),cmp); //排序 float sum=0; int current=0; //已并入边数 for(int i=0;i<n+1;i++)root[i]=i; //初始化root数组 for(int i=0;i<nedge;i++) { int a=e[i].s,b=e[i].d; if(find(a)!=find(b)) { join(a,b); sum+=e[i].dis; current++; } if(current==n-1)break; //如果已经有n-1条边,就不继续了,最小生成树边数比结点数少1 } return sum; } int main() { int n; while(~scanf("%d",&n)) { float xy[n][2]; int p=0; for(int i=0;i<n;i++)scanf("%f%f",&xy[i][0],&xy[i][1]); for(int i=0;i<n;i++) //两两相连 { for(int j=i+1;j<n;j++) { e[p].s=i; e[p].d=j; e[p++].dis=sqrt((xy[i][0]-xy[j][0])*(xy[i][0]-xy[j][0])+(xy[i][1]-xy[j][1])*(xy[i][1]-xy[j][1])); } } printf("%.2f\n",kruskal(n,(n*(n-1))/2)); //边数为n*(n-1)/2 } }
最小生成树的模板题,开始看成了旅行商浪费好长时间。。。
#include<cmath>
#define N 100
#define INF 1000000
using namespace std;
int n;
double dis[N][N];
double d[N];
bool vis[N];
struct point{
double x, y;
}points[100];
double distant(point a, point b){
return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}
void init(int n){
for(int i = 0; i < n; i++){
cin >> points[i].x >> points[i].y;
}
double d;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
d = distant(points[i], points[j]);
dis[i][j] = d;
dis[j][i] = d;
}
}
}
double prim(){
fill(vis, vis + N, false);
fill(d, d + N, INF);
d[0] = 0;
double ret = 0;
for(int i = 0; i < n; i++){
int u = -1;
double MIN = INF;
for(int j = 0; j < n; j++){
if(vis[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
if(u == -1) return -1;
vis[u] = true;
ret += d[u];
for(int v = 0; v < n; v++){
if(vis[v] == false && dis[u][v] != INF && dis[u][v] < d[v]){
d[v] = dis[u][v];
}
}
}
return ret;
}
int main(){
double ret;
while(cin >> n){
init(n);
ret = prim();
printf("%.2f\n", ret);
}
return 0;
}
#include <iostream> #include <limits.h> #include <cmath> using namespace std; #define N 105 inline double getDist(double x1, double y1, double x2, double y2){ return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)); } void prim(int n, double c[N][N]){ double sum = 0; double *lowcost = new double[n]; int *closest = new int[n]; bool *s = new bool[n]; s[0] = true; for (int i = 1; i < n; i++){ lowcost[i] = c[0][i]; closest[i] = 0; s[i] = false; } for (int i = 1; i<n; i++){ double min = INT_MAX; int j = 0; for (int k = 1; k <n; k++){ if (lowcost[k]<min && (!s[k])){ min = lowcost[k]; j = k; } } sum += c[j][closest[j]]; s[j] = true; for (int k = 1; k < n; k++){ if ((c[j][k]<lowcost[k]) && (!s[k])){ lowcost[k] = c[j][k]; closest[k] = j; } } } cout << sum << endl; } int main(){ int n; double c[N][N] = {{0}}, coord[N][2]; while (cin >> n){ for (int i = 0; i<n; i++){ cin >> coord[i][0] >> coord[i][1]; } for (int i = 0; i<n; i++){ for (int j = 0; j<n; j++){ c[i][j] = getDist(coord[i][0], coord[i][1], coord[j][0], coord[j][1]); } } prim(n, c); } }
#include<stdio.h> #include<math.h> #include<algorithm> #define N 101 int Tree[N]; using namespace std; int FindRoot(int x){ if(Tree[x]==-1) return x; else{ Tree[x]=FindRoot(Tree[x]); return Tree[x]; } } typedef struct Edge{ int a,b; double distance; }Edge; typedef struct Point{ double x,y; }Point; int cmp(Edge a,Edge b){ return a.distance<b.distance; } double getdis(Point a,Point b){ return sqrt(pow(b.y-a.y,2)+pow(b.x-a.x,2)); } int main(){ int n; while(scanf("%d",&n)!=EOF){ Point p[N]; Edge e[N*(N-1)/2]; int i; for(i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); int size=0; for(i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ e[size].a=i; e[size].b=j; e[size++].distance=getdis(p[i],p[j]); } sort(e,e+size,cmp); for(i=1;i<=n;i++) Tree[i]=-1; int a,b; double d=0; for(i=0;i<size;i++){ a=FindRoot(e[i].a); b=FindRoot(e[i].b); if(a!=b){ Tree[b]=a; d+=e[i].distance; } } printf("%.2lf\n",d); } return 0; }
#include <bits/stdc++.h> using namespace std; /** * 首先利用kruskcal算法实现, * 算法实现的关键是并查集的实现 */ struct point{ double x; double y; point(double a=0,double b=0):x(a),y(b){} }v[105]; struct edge{ int a,b; double len; edge(int x=0,int y=0,double l=0):a(x),b(y),len(l){} bool operator< (const edge & e)const{ return this->len<e.len; } }e[10000]; int n; int parent[105]; /** * 并查集实现 */ void UFset(){//并查集初始化 for(int i=0;i<n;i++) parent[i]=-1; } int UFfind(int x){ //找到x节点所在树的根节点 int ret; for(ret=x;parent[ret]>=0;ret=parent[ret]); //优化方案 --压缩路径,方便后续查找 while(ret!=x){ int tmp=parent[x]; parent[x]=ret; x=tmp; } return ret; } void UFunion(int R1,int R2){ //合并R1 ,R2所在树 int root1=UFfind(R1); int root2=UFfind(R2); //parent[root1 root2]都是小于零的数 if(parent[root1]>parent[root2]){ parent[root2]+=parent[root1]; parent[root1]=root2; } else { parent[root1]+=parent[root2]; parent[root2]=root1; } } int main(){ while(cin>>n&&n){ for(int i=0;i<n;i++){ double x,y; cin>>x>>y; v[i]=point(x,y); } UFset(); // 构建边集合 int k=0; for(int i=0;i<n-1;i++){ for(int j=i+1;j<n;j++){ double len=sqrt(pow(v[i].x-v[j].x,2)+pow(v[i].y-v[j].y,2)); e[k++]=edge(i,j,len); } } double sum=0; //按边从小到大排序 sort(e,e+k); for(int i=0;i<k;i++){ int a=e[i].a; int b=e[i].b; int r1=UFfind(a); int r2=UFfind(b); if(r1!=r2){ sum+=e[i].len; UFunion(r1,r2); } } printf("%.2f\n",sum); } return 0; }
#include <algorithm> #include <cmath> #include <iostream> #include <vector> #include <set> using namespace std; //顶点结构体 using dot = struct dot { float x; float y; }; //边类 class line { public: int start; int end; float length; line(int s, int e, float l): start(s), end(e), length(l) {} bool static compare(line a, line b) { return (a.length < b.length); } }; int main() { int n; while (cin >> n) { vector<dot> dots(n); for (int i = 0; i < n; i++) cin >> dots[i].x >> dots[i].y; //计算所有可能的边的长度 vector<line> lines; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { float dx = dots[i].x - dots[j].x; float dy = dots[i].y - dots[j].y; float length = sqrt(dx * dx + dy * dy); lines.emplace_back(i, j, length); } } //按边长升序排序 sort(lines.begin(), lines.end(), line::compare); //Prim算法求最小生成树 set<int> s; //已加入树的点的集合 s.insert(0); //初始树只有0号点 float sum = 0; //循环直到所有顶点都加入树中 while (s.size() < dots.size()) { //寻找长度最小且连接树内和树外的边 for (int i = 0; i < lines.size(); i++) { if (s.find(lines[i].start) != s.end() && s.find(lines[i].end) == s.end()) { s.insert(lines[i].end); sum += lines[i].length; break; } else if (s.find(lines[i].end) != s.end() && s.find(lines[i].start) == s.end()) { s.insert(lines[i].start); sum += lines[i].length; break; } } } cout.setf(ios::fixed); cout.precision(2); cout << sum; } }
#include<iostream> #include<iomanip> #include<vector> #include<math.h> #include<algorithm> using namespace std; struct node{ int num; double x; double y; }; struct res{ double dis; int node1; int node2; res(double _dis,int _node1,int _node2){ dis=_dis; node1=_node1; node2=_node2; } }; int visit[110]; bool compare(res lhs,res rhs){ if(lhs.dis<rhs.dis){ return true; } else return false; } void Initset(int n){ for(int i=0;i<n;i++){ visit[i]=i; } } int findfather(int n){ if(visit[n]==n){ return n; } else return findfather(visit[n]); } int main(){ int n; cin>>n; vector<node>coordi(n); vector<res>dis; Initset(n+1); for(int i=0;i<n;i++){ cin>>coordi[i].x>>coordi[i].y; coordi[i].num=i+1; } for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ double distance=sqrt(pow(fabs(coordi[i].x-coordi[j].x),2)+pow(fabs(coordi[i].y-coordi[j].y),2)); int s=coordi[i].num; int t=coordi[j].num; res resnode(distance,s,t); dis.push_back(resnode); } } sort(dis.begin(),dis.end(),compare); double sum=0; int setnode=n; for(vector<res>::iterator it=dis.begin();it!=dis.end();it++){ int a=(*it).node1; int b=(*it).node2; int aroot=findfather(a); int broot=findfather(b); if(aroot!=broot){ visit[broot]=aroot; sum+=(*it).dis; setnode--; } if(setnode==1){ break; } } cout<<fixed<<setprecision(2)<<sum<<endl; return 0; }