牛客oj 习题11.4Freckles(Kruskal)&&习题11.5Jungle Roads(Kruskal)

 

题目链接:click here

思路:最小生成树模板题,输入的点处理成边即可。

 

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
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又要出现莫名其妙的错误。。

 

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
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;
} 

 

你可能感兴趣的:(王道相关练习,图论-最小生成树,其他oj)