题目大意:
Flatopia需要建更多公路,使得开车不离开公路可以到任何两个镇。Flatopian镇从1到N编号并且有坐标。每条公路连接两个镇,所有的公路都是直的。所有的公路都是双向的。公路可以相互交,司机只可以在公路的末端交换。
Flatopian政府想要最小化成本。然而,他们想保证任何两个镇 都是可以到达的。
输入:N,第一行镇子的数量,接下来的N行包括坐标。
接下来的一行M,代表现存铁路的数量,接下来的M行包括 铁路路线
解题思路:
最小生成树问题
代码入下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 755
typedef struct
{
int x, y;
int w;
}edge;
edge e[MAX*MAX/2];
int rank[MAX], father[MAX];
int cmp(const void *a, const void *b)
{
if ((*(edge *)a).w > (*(edge *)b).w)
return 1;
return -1;
}
void Make_Set(int x)
{
father[x] = x;
rank[x] = 0;
}
int Find_Set(int x)
{
if (x != father[x])
father[x] = Find_Set(father[x]);
return father[x];
}
void Link(int x, int y, int w)
{
if (rank[x] > rank[y]) father[y] = x;
else
{
father[x] = y;
if (rank[x] == rank[y]) rank[y]++;
}
}
void Kruskal(int point_amou, int edge_amou)
{
int i, x, y;
qsort(e, edge_amou, sizeof(edge), cmp);
for (i = 0; i < edge_amou; i++)
{
x = Find_Set(e[i].x);
y = Find_Set(e[i].y);
if (x != y)
{
Link(x, y, e[i].w);
printf("%d %d\n", e[i].x+1, e[i].y+1);
}
}
}
int main(void)
{
int T, N, M, i, j, cnt, s, t;
int a[755], b[755];
scanf("%d", &T);
while(T--)
{
scanf("%d", &N);
for(i = 0; i < N; i++)
{
scanf("%d %d", &a[i], &b[i]);
Make_Set(i);
}
cnt = 0;
for(i = 0; i < N; i++)
{
for(j = i+1; j < N; j++)
{
e[cnt].x = i;
e[cnt].y = j;
e[cnt].w = (a[i]-a[j])*(a[i]-a[j]) + (b[i]-b[j])*(b[i]-b[j]);
cnt++;
}
}
scanf("%d", &M);
for(i = 0; i < M; i++)
{
scanf("%d %d", &s, &t);
s--;
t--;
s = Find_Set(s);
t = Find_Set(t);
Link(s, t, 0);
}
Kruskal(N, cnt);
if(T) printf("\n");
}
return 0;
}