zoukankan      html  css  js  c++  java
  • [暑假集训Day2T3]团建活动

    个人认为这周题中较难的一道。

    题意大概为:给定一张N个点M条边的无向图,求出无向图的一棵最小生成树,满足一号节点的度数不超过给定的整数K。保证 N <= 20

    首先用map存取节点,之后抛去1号节点,求每一个联通分量的MST,就得到了一个局部最优解,设p为联通块的个数,接下来从每一个联通分量中找一个离1号节点距离最近的点,连接其与1号节点的边,就得到了一棵1号节点度数为p的生成树,之后逐渐放宽限制,枚举最终答案的度数,每次从1号节点往其他点连边,会形成一个环,求出该点到1路径上形成的环中边权最大值,之后把这个最大值剪断,将1号节点和该点连边。直到减小不了权值为止

    下面给出标程(Author:????)

      1 #include <map>
      2 #include <cstdio>
      3 #include <string>
      4 #include <vector>
      5 #include <cstring>
      6 #include <iostream>
      7 #include <algorithm>
      8 using namespace std;
      9 const int N = 37, INF = 0x3f3f3f3f;
     10 struct E {
     11     int x, y, z;
     12     bool operator < (const E w) const
     13     {
     14         return z < w.z;
     15         }    
     16          
     17     }f[N];
     18 int n, k, tot, ans, a[N][N], fa[N], d[N], v[N];
     19 map<string, int> m;
     20 vector<E> e;
     21 bool b[N][N];
     22  
     23 int get(int x) {
     24     if (x == fa[x]) return x;
     25     return fa[x] = get(fa[x]);
     26 }
     27 // dfs(1,-1)
     28 void dfs(int x, int o) {
     29     for (int i = 2; i <= tot; i++) {
     30         if (i == o || b[x][i]==0) continue;
     31         if (f[i].z == -1) {
     32             if (f[x].z > a[x][i]) f[i] = f[x];
     33             else {
     34                 f[i].x = x;
     35                 f[i].y = i;
     36                 f[i].z = a[x][i];
     37             }
     38         }
     39         dfs(i, x);
     40     }
     41 }
     42  
     43 int main() {
     44     cin >> n;
     45     memset(a, 0x3f, sizeof(a));
     46     memset(d, 0x3f, sizeof(d));
     47     m["Park"] = tot = 1;
     48     for (int i = 0; i < N; i++) fa[i] = i;
     49     for (int i = 1; i <= n; i++) {
     50         E w;
     51         string s1, s2;
     52         cin >> s1 >> s2 >> w.z;
     53         w.x = m[s1] ? m[s1] : (m[s1] = ++tot);
     54         w.y = m[s2] ? m[s2] : (m[s2] = ++tot);
     55         e.push_back(w);
     56         a[w.x][w.y] = a[w.y][w.x] = w.z;
     57     }
     58     cin >> k;
     59     sort(e.begin(), e.end());
     60     for (unsigned int i = 0; i < e.size(); i++) {
     61         if (e[i].x == 1 || e[i].y == 1) continue;
     62         int rtx = get(e[i].x), rty = get(e[i].y);
     63         if (rtx != rty) {
     64             fa[rtx] = rty;
     65             b[e[i].x][e[i].y] = b[e[i].y][e[i].x] = 1;
     66             ans += e[i].z;
     67         }
     68     }
     69     for (int i = 2; i <= tot; i++)
     70         if (a[1][i] != INF) {
     71             int rt = get(i);
     72             if (d[rt] > a[1][i]) 
     73                 d[rt] = a[1][v[rt]=i]; // 记下每个父节点对应的边缘点以及边缘点和1号点的权值 
     74         }
     75     for (int i = 1; i <= tot; i++)
     76         if (d[i] != INF) {
     77             --k;
     78             b[1][v[i]] = b[v[i]][1] = 1;
     79             ans += a[1][v[i]];
     80         }
     81         //cout<<k<<endl;
     82     while (k--) {
     83         memset(f, -1, sizeof(f));
     84         f[1].z = -INF;
     85         for (int i = 2; i <= tot; i++)
     86             if (b[1][i]) f[i].z = -INF;
     87         dfs(1, -1);
     88         int o, w = -INF;
     89         for (int i = 2; i <= tot; i++)
     90             if (w < f[i].z - a[1][i])
     91                 w = f[i].z - a[1][o=i];
     92         if (w <= 0) break;
     93         //cout<<o<<endl;
     94         b[1][o] = b[o][1] = 1;
     95         b[f[o].x][f[o].y] = b[f[o].y][f[o].x] = 0;
     96         ans -= w;
     97     }
     98     printf("Total miles driven: %d
    ", ans);
     99     return 0;
    100 } 
    View Code
  • 相关阅读:
    windows下面安装Python和pip教程
    Python已安装第三方库
    Python安装cx_Oracle第三方库(Mac osx Yosemite Intel i5环境)
    7.Python进阶_函数对象
    6.Python进阶_循环对象
    5.Python进阶_循环设计
    UltraEdit中粘贴问题
    UltraEdit的代码片的编码设置
    使用C#实现SSLSocket加密通讯 Https
    sql while 循环要加begin end
  • 原文地址:https://www.cnblogs.com/szmssf/p/11172528.html
Copyright © 2011-2022 走看看