标签:
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