首页 > 代码库 > uva 3592 (MST, kruskal)

uva 3592 (MST, kruskal)

题意:平面上有若干个点,求最小生成树。有最多8个套餐,每个套餐有一个价格和若干个点,一旦购买套餐内的点就会相互连通。

思路:由于套餐不是很多,所以枚举一下即可,然后最小生成树就行了。

代码如下:

  1 /**************************************************  2  * Author     : xiaohao Z  3  * Blog     : http://www.cnblogs.com/shu-xiaohao/  4  * Last modified : 2014-06-23 22:36  5  * Filename     : uva_3592.cpp  6  * Description     :   7  * ************************************************/  8   9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <cmath> 14 #include <algorithm> 15 #include <queue> 16 #include <stack> 17 #include <vector> 18 #include <set> 19 #include <map> 20 #define MP(a, b) make_pair(a, b) 21 #define PB(a) push_back(a) 22  23 using namespace std; 24 typedef long long ll; 25 typedef pair<int, int> pii; 26 typedef pair<unsigned int,unsigned int> puu; 27 typedef pair<int, double> pid; 28 typedef pair<ll, int> pli; 29 typedef pair<int, ll> pil; 30  31 const int INF = 0x3f3f3f3f; 32 const double eps = 1E-6; 33 const int LEN = 1010; 34 int n, m, top, cost[LEN], parent[LEN]; 35 vector<int> Set[LEN]; 36 struct Point{int x, y;}p[LEN]; 37  38 struct Edge{ 39     int u, v, val; 40     void set(int _u, int _v, int _val){ 41         u = _u; v = _v; val = _val; 42     } 43 }edge[LEN*LEN]; 44 bool cmp(Edge a, Edge b){return a.val < b.val;} 45  46 //UFSet 47 void UFSet_init(){for(int i=0; i<LEN; i++) parent[i] = i;} 48 int Find(int x){return parent[x] == x ? x : parent[x] = Find(parent[x]);} 49 void Union(int a, int b) {int fa = Find(a), fb = Find(b);if(fa!=fb)parent[fa] = fb;} 50  51 void init(){ 52     for(int i=0; i<LEN; i++) 53         Set[i].clear(); 54     top = 0; 55 } 56  57 //kruskal 58 int kruskal(int x){ 59     UFSet_init(); 60     int ret = 0; 61     for(int i=0; i<m; i++)if((1<<i) & x){ 62         ret += cost[i]; 63         for(int j=1; j<Set[i].size(); j++){ 64             Union(Set[i][j], Set[i][0]); 65         } 66     } 67     for(int i=0; i<top; i++){ 68         int a = edge[i].u, b = edge[i].v; 69         int val = edge[i].val; 70         int pa = Find(a), pb = Find(b); 71         if(pa != pb){ 72             parent[pa] = pb; 73             ret += val; 74         } 75     } 76     return ret; 77 } 78  79 int dis(int a, int b){ 80     return (p[a].x - p[b].x)*(p[a].x - p[b].x)  81             + (p[a].y - p[b].y)*(p[a].y - p[b].y); 82 } 83  84 int main() 85 { 86 //    freopen("in.txt", "r", stdin); 87  88     int T, tn, num; 89     scanf("%d", &T); 90     while(T--){ 91         scanf("%d%d", &n, &m); 92         init(); 93         for(int i=0; i<m; i++){ 94             scanf("%d%d", &tn, &cost[i]); 95             for(int j=0; j<tn; j++){ 96                 scanf("%d", &num); 97                 num --; 98                 Set[i].PB(num); 99             }100         }101         for(int i=0; i<n; i++){102             scanf("%d%d", &p[i].x, &p[i].y);103         }104         for(int i=0; i<n; i++){105             for(int j=i+1; j<n; j++){106                 edge[top++].set(i, j, dis(i, j));107             }108         }109         int ans = INF;110         sort(edge, edge+top, cmp);111         for(int i=0; i<(1<<m); i++){112             ans = min(ans, kruskal(i));113         }114         printf("%d\n", ans);115         if(T != 0) puts("");116     }117     return 0;118 }
View Code