题目:
链接:点击打开链接
题意:
部分建筑已经被电缆连接,问还需要多长的电缆才能全部连起来。
思路:
初始时,把连接的建筑之间的dis[]设为0,然后Kruskal就好。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 800;
const int M = 300000;
int n,m;
int p[N],u[M],v[M],r[M];
double x[N],y[N];
double dis[M],ans;
int map[N][N],ct;
int cmp(const int i,const int j)
{
return dis[i] < dis[j];
}
int findset(int x)
{
return p[x] == x ? x : p[x] = findset(p[x]);
}
void kruskal()
{
ans = 0;
for(int i=0; i<n; i++)
p[i] = i;
sort(r,r+ct,cmp);
for(int i=0; i<ct; i++)
{
int e = r[i];
int x = findset(u[e]);
int y = findset(v[e]);
if(x != y)
{
ans += dis[e];
p[x] = y;
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
double d1,d2;
int st,ed;
while(scanf("%d",&n) != EOF)
{
ct = 0;
memset(map,0,sizeof(map));
for(int i=0; i<n; i++)
{
scanf("%lf%lf",&x[i],&y[i]);
}
scanf("%d",&m);
for(int i=0; i<m; i++)
{
scanf("%d%d",&st,&ed);
st--;
ed--;
map[st][ed] = map[ed][st] = 1;
}
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
u[ct] = i;
v[ct] = j;
r[ct] = ct;
if(map[i][j])
dis[ct++] = 0;
else
{
d1 = x[i] - x[j];
d2 = y[i] - y[j];
dis[ct++] = sqrt(d1*d1 + d2*d2);
}
}
}
kruskal();
printf("%.2lf\n",ans);
}
return 0;
}
---------------------------------------------------------------------------
收获:
----->把已经连通的dis设为0......................................
---------------------------------------------------------------------------
战斗,从不退缩;奋斗,永不停歇~~~~~~~~~~~~~~~~