zoukankan      html  css  js  c++  java
  • 【Uva1151】Buy or Build

    https://vjudge.net/problem/UVA-1151

    题意:给n个点,连接点i和点j的边的花费为两点的欧几里得距离,有q套构成,可以直接使用对应的花费将套餐中的点加入生成树,也可以直接建边,求最小生成树。

    思路:先对n个点进行一次Kruskal,之后对套餐的选中与否进行状态压缩,遍历所有情况即可。

      1 #include <bits/stdc++.h>
      2 #define fi first
      3 #define se second
      4 #define pb(i) push_back(i)
      5 #define rep(i, a, b) for (int i = a; i <= b; i++)
      6 #define per(i, a, b) for (int i = b; i >= a; i--)
      7 #define mem(a, b) memset(a, b, sizeof(a))
      8 #define VI vector<int>
      9 #define VLL vector<ll>
     10 #define MPII map<pair<int, int>, int>
     11 #define mp make_pair
     12 #define PQI priority_queue<int>
     13 #define lowbit(x) x & -x
     14 #define debug(a) cout << #a << '=' << a << '
    '
     15 using namespace std;
     16 typedef long long ll;
     17 typedef unsigned long long ull;
     18 const int N = 1e6 + 10;
     19 const int INF = 0x3f3f3f3f;
     20 const int inf = -INF;
     21 const int mod = 1e9 + 7;
     22 const double pi = acos(-1.0);
     23 const double eps = 1e-5;
     24 
     25 int n, q;
     26 int p[1005];
     27 int x[1005], y[1005];
     28 vector<int> subn[10];
     29 int cost[10];
     30 int find(int x)
     31 {
     32     return p[x] == x ? x : p[x] = find(p[x]);
     33 }
     34 struct Edge
     35 {
     36     int u, v, d;
     37     Edge(int u, int v, int d) : u(u), v(v), d(d){};
     38     bool operator<(const Edge T) const
     39     {
     40         return d < T.d;
     41     }
     42 };
     43 int Kruskal(int cnt, vector<Edge> &e, vector<Edge> &res)
     44 {
     45     if (cnt == 1)
     46         return 0;
     47     int m = e.size();
     48     int ans = 0;
     49     res.clear();
     50     for (int i = 0; i < m; i++)
     51     {
     52         int u = find(e[i].u), v = find(e[i].v);
     53         if (u != v)
     54         {
     55             ans += e[i].d;
     56             p[v] = u;
     57             res.push_back(e[i]);
     58             if (--cnt == 1)
     59                 break;
     60         }
     61     }
     62     return ans;
     63 }
     64 int main()
     65 {
     66     int T;
     67     scanf("%d", &T);
     68     while (T--)
     69     {
     70         scanf("%d%d", &n, &q);
     71         for (int i = 0; i < q; i++)
     72         {
     73             int k;
     74             scanf("%d%d", &k, &cost[i]);
     75             subn[i].clear();
     76             for (int u, j = 0; j < k; j++)
     77             {
     78                 scanf("%d", &u);
     79                 subn[i].push_back(u - 1);
     80             }
     81         }
     82         for (int i = 0; i < n; i++)
     83             scanf("%d%d", &x[i], &y[i]);
     84         vector<Edge> e, need;
     85         for (int i = 0; i < n; i++)
     86         {
     87             for (int j = i + 1; j < n; j++)
     88             {
     89                 int d = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
     90                 e.push_back(Edge(i, j, d));
     91             }
     92         }
     93         for (int i = 0; i < n; i++)
     94             p[i] = i;
     95         sort(e.begin(), e.end());
     96         int ans = Kruskal(n, e, need);
     97         for (int mask = 0; mask < (1 << q); mask++)
     98         {
     99             for (int i = 0; i < n; i++)
    100                 p[i] = i;
    101             int cnt = n, c = 0;
    102             for (int i = 0; i < q; i++)
    103             {
    104                 if (mask & (1 << i))
    105                 {
    106                     c += cost[i];
    107                     for (int j = 1; j < subn[i].size(); j++)
    108                     {
    109                         int u = find(subn[i][j]), v = find(subn[i][0]);
    110                         if (u != v)
    111                         {
    112                             p[v] = u;
    113                             cnt--;
    114                         }
    115                     }
    116                 }
    117             }
    118             vector<Edge> res;
    119             ans = min(ans, c + Kruskal(cnt, need, res));
    120         }
    121         printf("%d
    ", ans);
    122         if(T) printf("
    ");
    123     }
    124     system("pause");
    125     return 0;
    126 }
  • 相关阅读:
    POJ 3468 A Simple Problem with Integers(线段树 区间更新)
    Windows Mobile 6.0 SDK和中文模拟器下载
    Linux学习笔记——例说makefile 头文件查找路径
    uva 11427
    腾讯2014年实习生招聘笔试面试经历
    AVC1与H264的差别
    oracle递归函数
    全部编程皆为Web编程
    JavaScript--语法2--语句结构
    JavaScript--变量和运算符
  • 原文地址:https://www.cnblogs.com/yoshinaripb/p/14050817.html
Copyright © 2011-2022 走看看