題目大意
給出n個點,m條邊,刪除一些邊,使圖上不存在一個封閉圖形。
n<=10000,m<=50000
時間限制 1s
空間限制 256M
解題思路
要使刪除的邊長度最小,就是剩下的邊長度最大。而且圖上不能有環,所以可以用最小生成樹求解。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 10006
#define maxm 50006
#define fr(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
struct nod
{
int x,y;
double z;
} l[maxm];
double sqr(int x)
{
return x*x;
}
double dist(int x,int y,int w,int v)
{
return sqrt(sqr(x-w)+sqr(y-v));
}
bool cmp(nod a,nod b)
{
return a.z>b.z;
}
int i,n,m,fa[maxn],a[maxn][3];
double ans;
int get(int x)
{
if (fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
int main()
{
scanf("%d%d",&n,&m);
fr(i,1,n) scanf("%d%d",&a[i][1],&a[i][2]);
ans=0;
fr(i,1,m)
{
scanf("%d%d",&l[i].x,&l[i].y);
l[i].z=dist(a[l[i].x][1],a[l[i].x][2],a[l[i].y][1],a[l[i].y][2]);
ans+=l[i].z;
}
sort(l+1,l+m+1,cmp);
fr(i,1,n) fa[i]=i;
fr(i,1,m)
{
int t1=get(l[i].x),t2=get(l[i].y);
if (t1!=t2)
{
fa[t1]=t2;
ans-=l[i].z;
}
}
printf("%.6f\n",ans);
return 0;
}