标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2594 Accepted Submission(s): 1196
题目大意:
这道题是说,给你n个点,然后要求p和q号城市之间必须有道路相连接,然后,其他的道路之间满足最小生成树。说白了,就是一个 一条边固定的最小生成树问题。
解题思路:
直接用并查集搞就行了,没有什么难度。。。
代码:
# include<cstdio>
# include<iostream>
# include<cmath>
# include<cstring>
# include<algorithm>
using namespace std;
# define MAX 54*54
struct node
{
int x,y;
}point[MAX];
int f[MAX];
void init()
{
for ( int i = 0;i < MAX;i++ )
{
f[i] = i;
}
}
struct edge
{
int u,v;
double cost;
}e[MAX];
int cmp( const struct edge & a,const struct edge & b )
{
return a.cost < b.cost;
}
double dis ( node a,node b )
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) );
}
int getf( int x )
{
if ( f[x]==x )
return x;
else
{
int t = getf(f[x]);
f[x] = t;
return f[x];
}
}
int main(void)
{
int n;
while ( scanf("%d",&n)!=EOF )
{
if ( n==0 )
break;
init();
int p,q; scanf("%d%d",&p,&q);
for ( int i = 1;i <= n;i++ )
{
scanf("%d%d",&point[i].x,&point[i].y);
}
int cnt = 0;
for ( int i = 1;i <= n-1;i++ )
{
for ( int j = i+1;j <= n;j++ )
{
if( i==p&&j==q||i==q&&j==p )
{
e[cnt].cost = 0;
}
else
{
e[cnt].cost = dis(point[i],point[j]);
}
e[cnt].u = i; e[cnt].v = j;
cnt++;
}
}
int num = 0;
double ans = 0;
sort(e,e+cnt,cmp);
ans = dis(point[p],point[q]);
for ( int i = 0;i < cnt;i++ )
{
int x = getf(e[i].u);
int y = getf(e[i].v);
if ( x!=y )
{
num++;
f[x] = y;
ans+=e[i].cost;
if(num==n-1)
break;
}
}
printf("%.2lf\n",ans);
memset(e,0,sizeof(e));
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/wikioibai/p/4772084.html