题目大意:
给出背上斑点的坐标,求连接这些斑点所用的最少的墨水。
思路:
最小生成树
代码:
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <algorithm>
double x[105],y[105];
double dis[5050];//i,j之间的权值
int flag[5050];//编号
int jihe[5050];//i属于哪个集合
int u[5050],v[5050];
int n,m;
double sum;
int cmp(const int i,const int j) {
return dis[i] < dis[j] ;
}
int find(int i) {
if(jihe[i] == i)
return i;
else
return jihe[i] = find(jihe[i]);
// return jihe[i] == i ? i : jihe[i] = find(jihe[i]);
}
void kruskal() {
sum = 0;
for(int i = 0; i < n; i++)
jihe[i] = i;//每一点都属于一个集合
sort(flag,flag + m, cmp);
for(int i = 0; i < m; i++) {
int k = flag[i];
int x = find(u[k]);
int y = find(v[k]);
if(x != y) {
sum = sum + dis[k];
jihe[x] = y;
}
}
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
// memset(flag,0,sizeof(flag));
// memset(jihe,0,sizeof(jihe));
for(int i = 0; i < n; i++)
scanf("%lf %lf",&x[i],&y[i]);
m = 0;
for(int i = 0 ; i < n; i++) {
for(int j = i + 1; j < n ; j++) {
dis[m] =sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
u[m] = i;
v[m] = j;
flag[m] = m++;
}
}
kruskal();
printf("%.2lf\n",sum);
if(T)
printf("\n");
}
return 0;
}
prim:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <cmath>
int n;
double x[105],y[105];
double w[105][105];
int pre[105];
double minCost[105];
int hash[105];
double Prim() {
double sum = 0;
memset(hash,0,sizeof(hash));
hash[1] = 1;
for(int i = 1; i <= n; i++) {
minCost[i] = w[1][i];
pre[i] = 1;
}
int u = -1;
for(int i = 1; i < n; i++) {
u = -1;
for(int j = 1; j <= n; j++)
if(!hash[j]) {
if(u == -1 || minCost[j] < minCost[u])
u = j;
}//找出权值的最小值
sum += w[pre[u]][u];
hash[u] = 1;
for(int j = 1; j <= n; j++)
if(!hash[j]) {
if(minCost[j] > w[u][j]) {
minCost[j] = w[u][j];
pre[j] = u;
}//跟u关联的权值如果小于mincost就更新
}
}
return sum;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%lf %lf",&x[i],&y[i]);
}
memset(w,0,sizeof(w));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
w[i][j] = sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
}
printf("%.2lf\n",Prim());
if(T)
printf("\n");
}
return 0;
}