Description

给定一张无向连通图,存在边权ccc与点权a" role="presentation">aaa。

加入KKK条特殊边,构造出这些边的边权使得存在一棵最小生成树使得所有点到1" role="presentation">111号点的距离(只考虑特殊边的长度)乘以该点点权的乘积最大。

n⩽1000000,m⩽300000,k⩽20n⩽1000000,m⩽300000,k⩽20n\leqslant1000000,m\leqslant300000,k\leqslant20

Solution

首先强制选择kkk条特殊边,然后做最小生成树。
这次选进MST" role="presentation">MSTMSTMST的边一定会选进最后的MSTMSTMST。所以先用这些边进行缩点,这样就只剩kkk条特殊边和至多k2" role="presentation">k2k2k^2条特殊边。
直接O(k2)O(k2)O(k^2)枚举选择哪些特殊边,然后用k2k2k^2条非特殊边使树联通并求出每条特殊边的边权。
时间复杂度O(mlogm+2k×k2)O(mlogm+2k×k2)O(mlogm+2^k\times k^2)

#include <bits/stdc++.h>
using namespace std;typedef long long lint;
const int maxn = 100005, maxm = 300005;
const int Inf = 1 << 30;int n, m, cnt, tot, tp, root, c[35], fa[2][maxn], f[maxn], d[maxn];
lint siz[maxn], val[maxn];struct node {int u, v, w;bool operator < (const node &a) const {return w < a.w;}
}a[maxm], b[35];inline int gi()
{char c = getchar();while (c < '0' || c > '9') c = getchar();int sum = 0;while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar();return sum;
}int getfa(int k, int x)
{if (fa[k][x] == x) return x;else return fa[k][x] = getfa(k, fa[k][x]);
}struct edge {int to, next;
}e[maxn * 2];
int h[maxn], Tot;inline void add(int u, int v)
{e[++Tot] = (edge) {v, h[u]}; h[u] = Tot;e[++Tot] = (edge) {u, h[v]}; h[v] = Tot;
}void dfs(int u)
{siz[u] = val[u];for (int i = h[u], v; v = e[i].to, i; i = e[i].next) if (v != fa[1][u]) {fa[1][v] = u; d[v] = d[u] + 1; dfs(v);siz[u] += siz[v];}
}int main()
{n = gi(); m = gi(); cnt = gi();for (int i = 1; i <= m; ++i) a[i] = (node) {gi(), gi(), gi()};sort(a + 1, a + m + 1);for (int i = 1; i <= n; ++i) fa[0][i] = fa[1][i] = i;for (int u, v, i = 1; i <= cnt; ++i) {b[i].u = gi(); b[i].v = gi(); u = getfa(0, b[i].u), v = getfa(0, b[i].v);if (u != v) fa[0][u] = v;}for (int u, v, i = 1; i <= m; ++i) {u  = getfa(0, a[i].u); v = getfa(0, a[i].v);if (u != v) {fa[0][u] = v; fa[1][getfa(1, a[i].u)] = getfa(1, a[i].v);}}root = getfa(1, 1);for (int i = 1; i <= n; ++i) val[getfa(1, i)] += gi();for (int i = 1; i <= n; ++i) if (getfa(1, i) == i) c[++c[0]] = i;for (int i = 1; i <= cnt; ++i) b[i].u = getfa(1, b[i].u), b[i].v = getfa(1, b[i].v);for (int i = 1; i <= m; ++i) a[i].u = getfa(1, a[i].u), a[i].v = getfa(1, a[i].v);for (int u, v, i = 1; i <= m; ++i) {u = getfa(1, a[i].u), v = getfa(1, a[i].v);if (u != v) fa[1][u] = v, a[++tp] = a[i];}lint ans = 0;for (int k = 0; k < (1 << cnt); ++k) {Tot = 0;for (int u, i = 1; i <= c[0]; ++i) {u = c[i]; h[u] = fa[1][u] = 0;fa[0][u] = u; f[u] = Inf;}bool flag = true;for (int u, v, i = 1; i <= cnt; ++i)if (k & (1 << (i - 1))) {u = getfa(0, b[i].u); v = getfa(0, b[i].v);if (u == v) {flag = false; break;} fa[0][u] = v;add(b[i].u, b[i].v);}if (!flag) continue;for (int u, v, i = 1; i <= cnt; ++i) {u = getfa(0, a[i].u); v = getfa(0, a[i].v);if (u != v) {fa[0][u] = v; add(a[i].u, a[i].v);}}dfs(root);for (int u, v, i = 1; i <= cnt; ++i) {u = a[i].u; v = a[i].v;if (d[u] < d[v]) swap(u, v);while (d[u] != d[v]) f[u] = min(f[u], a[i].w), u = fa[1][u];while (u != v) {f[u] = min(f[u], a[i].w); f[v] = min(f[v], a[i].w);u = fa[1][u]; v = fa[1][v];}}lint tmp = 0;for (int u, v, i = 1; i <= cnt; ++i)if (k & (1 << (i - 1))) {u = b[i].u; v = b[i].v;if (d[u] < d[v]) swap(u, v);tmp += siz[u] * f[u];}ans = max(ans, tmp);}printf("%lld\n", ans);return 0;
}

[APIO2013]道路费用相关推荐

  1. [BZOJ3206][Apio2013]道路费用

    [BZOJ3206][Apio2013]道路费用 试题描述 输入 第一行包含三个由空格隔开的整数N,M和K.接下来的 M行描述最开始的M 条道路.这M行中的第i行包含由空格隔开的整数ai,bi和c i ...

  2. APIO2013 道路费用

    题目链接 大意是说,调整k条特殊边边的值,并在原图的基础上构建最小生成树.使得经过所有特殊边的值之和最大. 感谢dasxxx学长指出题目要素(加上新边,两点之间最多只有一条边),请各位在理解下文解法时 ...

  3. P3639-[APIO2013]道路费用【最小生成树】

    正题 题目链接:https://www.luogu.com.cn/problem/P3639 题目大意 给出nnn个点mmm条有边权的无向图,然后再给出kkk条边权未定义的边,然后每个点有一个人数pi ...

  4. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  5. [总结]2019年9月 OI学习/刷题记录

    从现在开始记录一下每天的学习情况.主力LOJ? 2019/9/5 LibreOJ #2543. 「JXOI2018」排序问题 答案显然是\(\frac{(n+m)!}{Cnt_1!Cnt_2!\cdo ...

  6. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  7. adas记录仪app_免费用的ADAS 极目启行APP道路测试

    [ZOL汽车电子]在年中点金展上第一次接触到极目这个品牌,它是一家专门从事ADAS驾驶辅助系统研发的科技公司,通过计算机视觉和图像算法研发出一系列的驾驶辅助产品.随着自动驾驶的话题不断升温,ADAS驾 ...

  8. c语言最小费用流_策略算法工程师之路-图优化算法(一)(二分图amp;最小费用最大流)...

    目录 1.图的基本定义 2.双边匹配问题 2.1 二分图基本概念 2.2 二分图最大匹配求解 2.3 二分图最优匹配求解 2.4 二分图最优匹配建模实例 2.4.1 二分图最优匹配在师生匹配中的应用 ...

  9. 华为式创新与海尔式创新——两条道路考验中国制造

    来源:企业管理杂志(ID:qyglzz) 作者:吴兴杰,中国管理科学研究院专家咨询委员会副主任.学术委员会委员.研究员 以华为为代表的聚合化创新之路非常难走而又不得不走,否则永远只能当二流甚至三流企业 ...

最新文章

  1. Interface Builder 和UIController的联系
  2. fluent计算进出口的流量差
  3. win10win键无反应_最新Science:强烷基CH键的无定向硼化作用
  4. Java基础学习笔记三 Java基础语法
  5. arraylist可以存储不同类型吗_结构胶的种类多吗?不同的类型有哪些产品特性?...
  6. setuptools清华源_setuptools与pip的依赖关系解决方案之间的差异
  7. 《王道计算机网络》学习笔记总目录+思维导图
  8. 关于Android 微信APP支付开发中遇到的问题
  9. 统计数字会撒谎-读书笔记
  10. 自定义点击弹出设置百度商桥
  11. yyyy-MM-dd 转化成 中国标准时间(Tue Dec 31 2019 00:00:00 GMT+0800 (中国标准时间))
  12. python统计套利_统计套利——反转定律
  13. win10定时关机c语言,win10定时关机在哪?win10设置定时关机的三种方法
  14. sql 语句in 使用占位符
  15. am335x 添加SPIamp;测试
  16. mysql中varchar与oracle中varchar2区别
  17. DVD刻录不可小觑:教你十二招刻录绝技
  18. js倒计时刷新页面不受影响
  19. java通过手机号查询联系人_在java中如何根据手机号查询号码归属地
  20. 罗斯蒙特3051变送器以后的发展方向

热门文章

  1. 解读涉密资质新旧标准承接范围的变化
  2. mysql+sqlyog的超详细完整安装+数据库基础知识
  3. 【论文翻译】HinCTI: 基于异构信息网络的网络威胁情报建模与识别系统
  4. sed命令:删除匹配行和替换
  5. 由对称性知定点一定在x轴上_在平面直角坐标系中,点P(x,y)为动点,已知点...
  6. loadrunner脚本编写(转载至虫师博客)
  7. 【论文-目标追踪】BoT-SORT: Robust Associations Multi-Pedestrian Tracking
  8. 又见到一个利用redis漏洞的活生生的例子
  9. 生物探针技术与使用现状
  10. 有感于《华裔博士难找工作加拿大自杀 曾是湖北理科状元》