题目——————》 hdu 4463
第一次写最小生成树。粗心犯了一个错误 调啊调啊调了半个多小时
然后陷入了理所当然的思维,调了一个多小时才找到错误。
诶
当 nike 和 apple 这条路是一定需要修建的 所以一开始我就把这两个顶点给直接排除掉了
然而 就也许会导致错误。啊 说的不清楚
直接看代码
我好饿。。。。先去吃饭 稍后补注释
用的是prim算法 之后会再补上k算法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<iomanip>
using namespace std;
struct Node //节点
{
int x;
int y;
};
Node node[52];
typedef struct graph{ //图
Node *vexs;
double matrix[52][52]; //用于记录i与j之间的权值
};
graph g;
double calculate(int x1, int x2, int y1, int y2){
return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2));
}
void createGraph(int n){ //创建全连通图
g.vexs = node;
double l;
for (int i = 1; i <= n; i++){
g.matrix[i][i] = 0;
for (int j = i+1; j <= n; j++){
l = calculate(node[i].x, node[j].x, node[i].y, node[j].y);
g.matrix[i][j] = g.matrix[j][i] = l;
}
}
}
double prim(int nike,int apple,int n){
int i,j,k;
double weights[52]; //此可以数组理解为 对于要加入当前节点时边的权值
double sum = g.matrix[nike][apple];
for (i = 1; i <= n; i++){ //将nike和apple这条加入,并且更新数组
weights[i] = g.matrix[apple][i];
if (weights[i] > g.matrix[nike][i]){
weights[i] = g.matrix[nike][i];
}
}
weights[nike] = 0;
for (i = 3; i <= n; i++){
double min = 100000;
for (j = 1; j <= n; j++){
if (weights[j] != 0 && weights[j] < min){
min = weights[j];
k = j;
}
}
sum += min;
weights[k] = 0;
for (j = 1; j <= n; j++){
if (weights[j] != 0 && g.matrix[k][j] < weights[j]){
weights[j] = g.matrix[k][j];
}
}
}
return sum;
}
int main(){
// freopen("TestDate.txt", "r", stdin);
int n;
int index_Nike;
int index_Apple;
while (cin >> n && n != 0){
cin >> index_Nike >> index_Apple;
for (int i = 1; i <= n; i++){
cin >> node[i].x >> node[i].y;
}
createGraph(n);
double result = prim(index_Nike, index_Apple, n);
cout << fixed << setprecision(2) << result << endl;
}
return 0;
}
补充K算法。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
using namespace std;
#define MAX 52
struct Node
{
int x;
int y;
};
Node node[MAX];
struct Edge
{
int index_a;
int index_b;
double weight;
};
Edge edge[MAX*(MAX - 1)];
double calculate(int x1, int x2, int y1, int y2){
return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2));
}
int createEdge(int n){
int i, j ,k;
k = 0;
for (i = 1; i <= n; i++){
for (j = i; j <= n; j++){
edge[k].index_a = i;
edge[k].index_b = j;
edge[k].weight = calculate(node[i].x, node[j].x, node[i].y, node[j].y);
k++;
}
}
return k;
}
bool compare(Edge a, Edge b){
return a.weight < b.weight;
}
int get_end(int vends[], int start){
int k = start,j = start;
while (vends[k] != k){
k = vends[k];
}
int swap;
while (vends[j] != k){
swap = vends[j];
vends[j] = k;
j = swap;
}
return k;
}
double kruskal(int nike,int apple,int edgenum,int n){
double result = 0;
int vends[MAX];
int i;
for (i = 1; i <= n; i++){
vends[i] = i;
}
for (i = 0; i < edgenum; i++){
if ((edge[i].index_a == nike && edge[i].index_b == apple) || (edge[i].index_a == apple && edge[i].index_b == nike)){
result += edge[i].weight;
vends[nike] = apple;
vends[apple] = apple;
edge[i].weight = 0;
break;
}
}
sort(edge, edge + edgenum, compare);
int k1, k2;
for (i = 0; i < edgenum; i++){
if (edge[i].weight == 0){
continue;
}
k1 = get_end(vends, edge[i].index_a);
k2 = get_end(vends, edge[i].index_b);
if (k1 != k2){
vends[k1] = k2;
result += edge[i].weight;
}
}
return result;
}
int main(){
freopen("TestDate.txt","r",stdin);
int n;
int index_Nike;
int index_Apple;
while (cin >> n && n != 0){
cin >> index_Nike >> index_Apple;
for (int i = 1; i <= n; i++){
cin >> node[i].x >> node[i].y;
}
int edgenum = createEdge(n);
double result = kruskal(index_Nike, index_Apple, edgenum,n);
cout << fixed << setprecision(2) << result << endl;
}
return 0;
}