最小生成树+Kruskal算法 并查集的使用
题目:http://poj.org/problem?id=2349
题目大意:最小生成树找第k大边。
直接Kruskal就把最小生成树跑出来,找第k大边就ok。而我的模板并查集下标从1开始。但是我的点从0开始。导致WA了。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=1e6+10;
struct Edge
{
int l, r;
double v;
}edge[maxn];
struct F
{
double x;
double y;
}f[maxn];
int cmp(Edge a, Edge b)
{
return a.v<b.v;
}
int cmp1(Edge a, Edge b)
{
return a.v>b.v;
}
int a[maxn];
int fd(int x)
{
while(a[x]>=0)//从0开始:>=0 从1开始: >0
x=a[x];
return x;
}
void lj(int x, int y)
{
x=fd(x);
y=fd(y);
if(x!=y)
{
if(a[x]<a[y])
a[x]+=a[y],a[y]=x;
else
a[y]+=a[x],a[x]=y;
}
}
vector<double> v;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
v.clear();
memset(a, -1, sizeof(a));
int k, n, p=0;
scanf("%d%d",&k,&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&f[i].x,&f[i].y);
}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
edge[p].v=sqrt((f[i].x-f[j].x)*(f[i].x-f[j].x)+(f[i].y-f[j].y)*(f[i].y-f[j].y));
edge[p].l=i, edge[p].r=j, p++;
edge[p].v=edge[p-1].v;
edge[p].l=j, edge[p].r=i, p++;
}
}
sort(edge, edge+p, cmp);
for(int i=0;i<p;i++)
{
if(fd(edge[i].l)!=fd(edge[i].r))
{
v.push_back(edge[i].v);
lj(edge[i].l, edge[i].r);
}
}
sort(v.begin(), v.end(), greater<double>() );
printf("%.2f\n",v[k-1]);
}
return 0;
}