Highways
原题链接https://vjudge.net/contest/352170#problem/G
题目给出n个地点以及n个地点的坐标,以及已经连接好的路,要求出连接剩下的路的最短路径需要连接的路,利用Kruskal正常记录路径,将已经连接的地点取出,进行特别连接,不记录,连接完成之后,在连接其他路径,并记录路径,最后将记录结果输出。
Kruskal:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
long long n;
long long cnt;
long long z;
long long pre[300005];
struct node
{
long long u;
long long v;
double w;
} stu[300005];
struct id
{
long long x;
long long y;
} idd[300005];
struct sum
{
long long u;
long long v;
} sum1[300005];
bool cmp(node x, node y)
{
return x.w < y.w;
}
long long find(long long x)
{
if (pre[x] == x)
{
return x;
}
return pre[x] = find(pre[x]);
}
void join(long long x, long long y, double w)
{
long long ss1 = find(x);
long long ss2 = find(y);
if (ss1 != ss2)
{
pre[ss1] = ss2;
cnt--;
if (w != 0)
{
sum1[z].u = x;
sum1[z].v = y;
z++;
}
}
}
int main()
{
cin >> n;
long long i, j;
z = 0;
for (i = 1; i <= n; i++)
{
pre[i] = i;
scanf("%lld %lld", &idd[i].x, &idd[i].y);
}
cnt = n;
long long k = 0;
for (i = 1; i < n; i++)
{
for (j = i + 1; j <= n; j++)
{
stu[k].u = i;
stu[k].v = j;
stu[k].w = sqrt(1.0 * (idd[i].x - idd[j].x) * (idd[i].x - idd[j].x) + 1.0 * (idd[i].y - idd[j].y) * (idd[i].y - idd[j].y));
k++;
}
}
long long m;
long long a, b;
sort(stu, stu + k, cmp);
scanf("%lld", &m);
while (m--)
{
scanf("%lld %lld", &a, &b);
join(a, b, 0.0);//特别标记,不记录
}
for (i = 0; i < k; i++)
{
join(stu[i].u, stu[i].v, stu[i].w);//正常计算,
if (cnt == 1)
{
break;
}
}
for (i = 0; i < z; i++)
{
printf("%lld %lld\n", sum1[i].u, sum1[i].v);
}
return 0;
}