zoukankan      html  css  js  c++  java
  • UVa1151 Buy or Build

    填坑(p.358)

    以前天真的以为用prim把n-1条边求出来就可以

    现在看来是我想多了

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6 
      7 const int N = 1000 + 10;
      8 
      9 struct Node {
     10     int x, y;
     11     Node(int x = 0, int y = 0) : x(x), y(y) {}
     12 }p[N];
     13 
     14 int sqr(int x) {
     15     return x * x;
     16 }
     17 
     18 int dist(const Node& a, const Node& b) {
     19     return sqr(a.x - b.x) + sqr(a.y - b.y);
     20 }
     21 
     22 struct Edge {
     23     int u, v, w;
     24     Edge() {}
     25     Edge(int u, int v, int w) : u(u), v(v), w(w) {}
     26     bool operator < (const Edge& rhs) const {
     27         return w < rhs.w;
     28     }
     29 };
     30 #include<vector>
     31 std::vector<Edge> edges, pree;
     32 
     33 int n, ans;
     34 int d[N], pre[N], dis[N][N];
     35 bool inMST[N];
     36 
     37 void prim() {
     38     memset(d, 0x3f, sizeof d);
     39     memset(inMST, 0, sizeof inMST);
     40     ans = d[0] = 0;
     41     for(int i = 0; i < n; i++) {
     42         int u = -1;
     43         for(int v = 0; v < n; v++) if(!inMST[v]) {
     44             if(u == -1 || d[v] < d[u]) u = v;
     45         }
     46         inMST[u] = 1;
     47         ans += d[u];
     48         if(i) edges.push_back(Edge(u, pre[u], dis[u][pre[u]]));
     49         for(int v = 0; v < n; v++) if(!inMST[v]) {
     50             if(d[v] > d[u] + dis[u][v]) {
     51                 d[v] = d[u] + dis[u][v];
     52                 pre[v] = u;
     53             }
     54         }
     55     }
     56 }
     57 
     58 int fa[N];
     59 int find(int x) {
     60     return fa[x] == x ? x : fa[x] = find(fa[x]);
     61 }
     62 
     63 bool merge(int x, int y) {
     64     x = find(x), y = find(y);
     65     if(x == y) return 0;
     66     return fa[x] = y, 1;
     67 }
     68 
     69 void UFS_init() {
     70     for(int i = 0; i < n; i++) fa[i] = i;
     71 }
     72 
     73 void pre_kruskal() {
     74     for(int i = 0; i < n; i++) {
     75         for(int j = i + 1; j < n; j++) {
     76             pree.push_back(Edge(i, j, dis[i][j]));
     77         }
     78     }
     79     sort(pree.begin(), pree.end());
     80     
     81     UFS_init();
     82     int MST = n;
     83     ans = 0;
     84     for(unsigned i = 0; i < pree.size(); i++) {
     85         const Edge& e = pree[i];
     86         if(merge(e.u, e.v)) {
     87             edges.push_back(e);
     88             ans += e.w;
     89             if(--MST == 1) break;
     90         }
     91     }
     92 }
     93 
     94 int q;
     95 #include<vector>
     96 std::vector<int> frees[10];
     97 int cost[10];
     98 #include<cassert>
     99 void Kruskal(int mask) {
    100     UFS_init();
    101     int MST = n, res = 0;
    102     for(int j = 0; j < q; j++) if(mask >> j & 1) {
    103         res += cost[j];
    104         for(unsigned i = 1; i < frees[j].size(); i++) {
    105             MST -= merge(frees[j][i-1], frees[j][i]);
    106         }
    107     }
    108     
    109     for(unsigned i = 0; i < edges.size(); i++) {
    110         if(MST == 1) break;
    111         if(merge(edges[i].u, edges[i].v)) res += edges[i].w, MST--;
    112     }
    113     assert(MST == 1);
    114     ans = std::min(ans, res);
    115 }
    116 
    117 int main() {
    118 #ifdef DEBUG
    119     freopen("in.txt", "r", stdin);
    120     freopen("out.txt", "w", stdout);
    121 #endif
    122     
    123     int T; scanf("%d", &T);
    124     while(T--) {
    125         pree.clear();
    126         edges.clear();
    127         scanf("%d%d", &n, &q);
    128         for(int i = 0; i < q; i++) {
    129             int m;
    130             scanf("%d%d", &m, cost + i);
    131             frees[i].resize(m);
    132             for(int j = 0; j < m; j++) {
    133                 scanf("%d", &frees[i][j]);
    134                 --frees[i][j]; 
    135             }
    136         }
    137         for(int i = 0; i < n; i++) {
    138             scanf("%d%d", &p[i].x, &p[i].y);
    139             for(int j = 0; j < i; j++) {
    140                 dis[i][j] = dis[j][i] = dist(p[i], p[j]);
    141             }
    142         }
    143         pre_kruskal();
    144         std::sort(edges.begin(), edges.end());
    145         for(int mask = 0; mask < (1 << q); mask++) {
    146             Kruskal(mask);
    147         }
    148         
    149         printf("%d
    ", ans);
    150         if(T) puts("");
    151     }
    152     
    153     return 0;
    154 }
    View Code
  • 相关阅读:
    ES6之主要知识点(二) 变量的解构赋值。默认值
    ES6之主要知识点(一)
    前后端通信
    js 面向对象类
    typeof 、Object.prototype.toString和 instanceof
    原型链 之 对象的创建
    Ueditor1.4.3.3+springMvc+maven 实现图片上传
    Hibernate 根据实体名称得到DB表名以及表对应的Sequence name
    第三章:对象的共享——java并发编程实战
    第二章:线程安全性——java并发编程实战
  • 原文地址:https://www.cnblogs.com/showson/p/5113312.html
Copyright © 2011-2022 走看看