UVa 10397 - Connect the Campus

来源:互联网 发布:出差携带知乎 编辑:程序博客网 时间:2024/05/21 16:22

题目:给你一些建筑,以及他们之间的一些电缆,问把他们都连起来还需要多少电缆。

分析:最小生成树。将已有的电缆长度定义为0,直接进行最小生成树算法即可。

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>using namespace std;typedef struct p_node{int x,y;}pnode;pnode p[755];double dist( int a, int b ){return sqrt(0.0+(p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));}typedef struct d_node{int point1;int point2;double weight;}enode;enode edge[565000];//union_setint sets[755];int rank[755];void set_inital( int a, int b ){for ( int i = a ; i <= b ; ++ i ) {rank[i] = 0;sets[i] = i;}}int  set_find( int a ){if ( a != sets[a] )sets[a] = set_find( sets[a] );return sets[a];}void set_union( int a, int b ){if ( rank[a] < rank[b] )sets[a] = b;else {if ( rank[a] == rank[b] )rank[a] ++;sets[b] = a;}}//end_union_setint cmp_e( enode a, enode b ){return a.weight < b.weight;}double kruskal( int n, int r ){set_inital( 1, n );sort( edge, edge+r, cmp_e );double sum = 0;for ( int i = 0 ; i < r ; ++ i ) {int A = set_find( edge[i].point1 );int B = set_find( edge[i].point2 );if ( A != B ) {set_union( A, B );sum += edge[i].weight;}}return sum;}int smap[755][755];int main(){int n,m,a,b;while ( scanf("%d",&n) != EOF ) {memset( smap, 0, sizeof(smap) );for ( int i = 1 ; i <= n ; ++ i )scanf("%d%d",&p[i].x,&p[i].y);scanf("%d",&m);for ( int i = 1 ; i <= m ; ++ i ) {scanf("%d%d",&a,&b);smap[a][b] = smap[b][a] = 1;}int r = 0;for ( int i = 1 ; i <= n ; ++ i )for ( int j = 1 ; j < i ; ++ j ) {edge[r].point1 = i;edge[r].point2 = j;edge[r].weight = (!smap[i][j])*dist( i, j );r ++;}printf("%.2lf\n",kruskal( n, r ));}return 0;}

0 0
原创粉丝点击