题目:有一些电脑,电脑间由一些线路连接。现在给你电脑间的连接状态,以及原来选取的网络线路。
在此基础上加入了K条新线路,要从里面选取新的网络,使得电脑都连通并且线路长度和最小。
分析:图论、最小生成树。
说明:每组数据间有空行。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; typedef struct d_node { int point1; int point2; int weight; }enode; enode edge[1000010]; //union_set int sets[1000010]; int rank[1000010]; 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_set int cmp_e( enode a, enode b ) { return a.weight < b.weight; } int kruskal( int n, int m ) { sort( edge, edge+m, cmp_e ); set_inital( 0, n ); int sum = 0; for ( int i = 0 ; i < m ; ++ 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 main() { int N,K,M,u,v,w,c = 0; while ( ~scanf("%d",&N) ) { int old_cost = 0; for ( int i = 1 ; i < N ; ++ i ) { scanf("%d%d%d",&u,&v,&w); old_cost += w; } int e_count = 0; scanf("%d",&K); for ( int i = 0 ; i < K ; ++ i ) { scanf("%d%d%d",&u,&v,&w); edge[e_count].point1 = u; edge[e_count].point2 = v; edge[e_count].weight = w; e_count ++; } scanf("%d",&M); for ( int i = 0 ; i < M ; ++ i ) { scanf("%d%d%d",&u,&v,&w); edge[e_count].point1 = u; edge[e_count].point2 = v; edge[e_count].weight = w; e_count ++; } if ( c ++ ) printf("\n"); printf("%d\n%d\n",old_cost,kruskal( N, e_count )); } return 0; }
UVa 908 - Re-connecting Computer Sites,布布扣,bubuko.com
时间: 2024-10-09 12:17:01