最小生成树 ——kruscal算法和prim算法
kruscal算法
代码:
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct Island
{
int x, y;
} arr[500];
struct node
{
int u, v;
double w;
} edge[2000];
int per[220];
int n;
bool cmp(node a,node b)
{
return a.w < b.w;
}
void init()
{
for(int i=1; i<=n; ++i)
{
per[i]=i;
}
}
int find(int x)
{
if(x==per[x]) return x;
return per[x]=find(per[x]);
}
bool join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
per[fx]=fy;
return 1;
}
return 0;
}
int main()
{
int T;
int i, j, k;
double x, y;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
init();
for(i = 1; i <= n; i++)
{
scanf("%d%d", &arr[i].x, &arr[i].y);
}
k=0;
for(i = 1; i <= n; i++) //把所有路记录在node结构体中
{
for(j = i+1; j <= n; j++)
{
edge[k].u = i;
edge[k].v = j;
x = (arr[j].y-arr[i].y) * (arr[j].y-arr[i].y);
y = (arr[j].x-arr[i].x) * (arr[j].x-arr[i].x);
double temp = sqrt(x+y);
edge[k++].w = temp;
}
}
sort(edge, edge+k, cmp);
double sum = 0;
for(i = 0; i < k; i++)
{
if(edge[i].w <= 1000 && edge[i].w >= 10 && join(edge[i].u,edge[i].v))//如果两个岛的距离不符合要求就会把join(edge[i].u,edge[i].v)短路
{
sum += edge[i].w;
}
}
int cnt = 0;
bool flag = 0;
for(i = 1; i <= n; i++) //短路了就不会执行了,也就不会连接了,就只需要判断根节点的个数
{
if(i == per[i]) cnt++;
if(cnt > 1) //不等于1就还有元素(小岛)没连起来,不满足题意
{
flag = 1;
break;
}
}
if(flag) printf("oh!\n");
else
printf("%.1lf\n", sum*100);
}
return 0;
}
prim算法
代码:
#include <cstdio>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
struct nod
{
double x, y, w;
}node[105];
double map[105][105], sum;
int s[105], n;
void set()
{
double d;
for(int i = 1; i <= n; i++)
{
s[i]=0; node[i].w = INF;
for(int j = i + 1; j <= n; j++)
{
d = sqrt(pow(node[i].x-node[j].x, 2) + pow(node[i].y-node[j].y, 2));
if(d >= 10 && d <= 1000)
map[i][j] = map[j][i] = d*100;
else
map[i][j] = map[j][i] = INF;
}
}
}
int Prim(int m)
{
double min;
int t = 1;
s[m] = 1; sum=0;
for(int k = 2; k <= n; k++)
{
for(int i = 1; i <= n; i++)
if(s[i] == 0 && node[i].w > map[m][i])
node[i].w = map[m][i];
min = INF;
for(int j = 1; j <= n; j++)
if(s[j] == 0 && min > node[j].w)
{
min = node[j].w;
m = j;
}
if(s[m] == 0)
{
t++;
sum += min;
s[m] = 1;
}
}
if(t == n) return 1;
return 0;
}
int main()
{
int t, k;
scanf("%d", &k);
while(k--)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%lf%lf", &node[i].x, &node[i].y);
set();
t = Prim(1);
if(t != 0)
printf("%.1lf\n", sum);
else
printf("oh!\n");
}
}