题目链接:click here
思路:最小生成树模板题,输入的点处理成边即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 105;
const int INF = INT_MAX;
struct Point{
double x;
double y;
};
struct Edge{
int SourceA;
int SourceB;
double length;
bool operator< (const Edge& c) const {
return length < c.length;
}
};
int n;
Point point[MAXN];
Edge edge[MAXN * MAXN];
int father[MAXN], height[MAXN];
int Find(int x){
if(x != father[x]) father[x] = Find(father[x]);
return father[x];
}
void Union(int x, int y){
if(height[x] < height[y]) father[x] = y;
else if(height[y] < height[x]) father[y] = x;
else{
father[y] = x;
height[x]++;
}
}
double Kruskal(int edgenum){
sort(edge, edge + edgenum);
int x, y;
double sum = 0;
for(int i = 0; i < edgenum; i++){
x = edge[i].SourceA;
y = edge[i].SourceB;
x = Find(x);
y = Find(y);
if(x != y){
Union(x, y);
sum += edge[i].length;
}
}
return sum;
}
void Initial(){
for(int i = 0; i < n; i++){
father[i] = i;
height[i] = 0;
}
}
int main(){
// freopen("in.txt", "r", stdin);
while(~scanf("%d", &n)){
Initial();
for(int i = 0; i < n; i++){
scanf("%lf %lf", &point[i].x, &point[i].y);
}
int count = 0;
double disX, disY;
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
edge[count].SourceA = i;
edge[count].SourceB = j;
disX = fabs(point[i].x - point[j].x);
disY = fabs(point[i].y - point[j].y);
edge[count].length = sqrt(disX * disX + disY * disY);
count++;
}
}
printf("%.2lf\n", Kruskal(count));
}
return 0;
}
题目链接:click here
裸最小生成树,不过输入时候因为是字符和数字混合输入,所以用cin方便一些,scanf又要出现莫名其妙的错误。。
扫描二维码关注公众号,回复:
10728333 查看本文章
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 55;
const int INF = INT_MAX;
struct Edge{
int SourceA;
int SourceB;
int length;
bool operator< (const Edge& c) const {
return length < c.length;
}
};
int n;
Edge edge[MAXN * MAXN];
int father[MAXN], height[MAXN];
int Find(int x){
if(x != father[x]) father[x] = Find(father[x]);
return father[x];
}
void Union(int x, int y){
if(height[x] < height[y]) father[x] = y;
else if(height[y] < height[x]) father[y] = x;
else{
father[y] = x;
height[x]++;
}
}
int Kruskal(int edgenum){
sort(edge, edge + edgenum);
int x, y;
int sum = 0;
for(int i = 0; i < edgenum; i++){
x = edge[i].SourceA;
y = edge[i].SourceB;
x = Find(x);
y = Find(y);
if(x != y){
Union(x, y);
sum += edge[i].length;
}
}
return sum;
}
void Initial(){
for(int i = 0; i < n; i++){
father[i] = i;
height[i] = 0;
}
}
int main(){
// freopen("in.txt", "r", stdin);
while(~scanf("%d", &n)){
if(n == 0) break;
Initial();
char A, B;
int nearnum, value, edgenum = 0;
for(int i = 0; i < (n - 1); i++){
cin >> A >> nearnum;
for(int j = 0; j < nearnum; j++){
cin >> B >> value;
edge[edgenum].SourceA = A - 'A';
edge[edgenum].SourceB = B - 'A';
edge[edgenum].length = value;
edgenum++;
}
}
printf("%d\n", Kruskal(edgenum));
}
return 0;
}