[BZOJ 1937][Shoi2004]Mst 最小生成树
$ \color{red} {solution:} $
对于每条树边\(i\),其边权只可能变小,对于非树边\(j\),其边权只可能变大,所以对于任意非树边覆盖的树边有 \(wi - di <= wj + dj\),
变形一下 \(wi - wj <= di +dj\), 而这一部分正是带权二分图匹配,可以使用\(KM\)算法
不会\(KM\)算法的同学这里有篇算法介绍;
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010, inf = 0x3f3f3f3f;
template <typename T> inline bool check_Max(T &x, const T &y) {
return x < y ? x = y, false : true;
}
template <typename T> inline bool check_Min(T &x, const T &y) {
return x > y ? x = y, false : true;
}
struct edge {int u, v, w; } E[maxn];
int v[maxn], to[maxn], head[maxn], pos[maxn], p;
inline void link(int a, int b, int c) {
v[++ p] = b; to[p] = head[a]; head[a] = p; pos[p] = c;
}
inline void init() {
p = 1; memset(head, 0, sizeof(head));
}
int dep[maxn], fa[maxn], rfe[maxn];
inline void dfs(int u, int f) {
dep[u] = dep[f] + 1; fa[u] = f;
for ( int i = head[u]; i; i = to[i]) if( v[i] ^ f)
rfe[v[i]] = i >> 1, dfs(v[i], u);
}
int a[1010][1010], pre[maxn], slack[maxn], vis[maxn], mat[maxn], tot;
int lv[maxn], rv[maxn];
inline void aug(int s) {
for ( int i = 0; i <= tot; ++ i) slack[i] = inf, vis[i] = pre[i] = 0;
int u = 0; mat[u] = s;
do {
int now = mat[u], d = inf, nxt; vis[u] = 1;
for ( int v = 1; v <= tot; ++ v) if( !vis[v]){
if( !check_Min(slack[v], lv[now] + rv[v] - a[now][v]))
pre[v] = u;
if( !check_Min(d, slack[v])) nxt = v;
}
for ( int i = 0; i <= tot; ++ i)
if( vis[i]) lv[mat[i]] -= d, rv[i] += d;
else slack[i] -= d;
u = nxt;
} while ( mat[u]);
while ( u) mat[u] = mat[pre[u]], u = pre[u];
}
int n, m;
int main() {
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
init();
scanf("%d%d", &n, &m); tot = max(n-1, m-n+1);
for ( int i = 1; i <= m; ++ i) {
scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
if( E[i].u > E[i].v) swap(E[i].u, E[i].v);
}
for ( int i = 1, u, v; i < n; ++ i) {
scanf("%d%d", &u, &v); if( u > v) swap(u, v);
for ( int k = 1; k <= m; ++ k) if( E[k].u == u && E[k].v == v) {
vis[k] = 1, link(u, v, E[k].w), link(v, u, E[k].w); break;
}
}
dfs(1, 0);
int num = 0;
for ( int i = 1; i <= m; ++ i) if( !vis[i]) {
int u = E[i].u, v = E[i].v, c; ++ num;
while ( u ^ v) {
if( dep[u] < dep[v]) swap(u, v);
c = rfe[u];
a[c][num] = pos[c << 1] - E[i].w; u = fa[u];
}
}
for ( int i = 1; i <= tot; ++ i)
for ( int k = 1; k <= tot; ++ k) check_Max(lv[i], a[i][k]);
for ( int i = 1; i < n; ++ i) aug(i);
int ans = 0;
for ( int i = 1; i <= tot; ++ i) ans += lv[i] + rv[i];
printf("%d\n", ans);
return 0;
}

[BZOJ 1937][Shoi2004]Mst 最小生成树的更多相关文章
- BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]
传送门 题意: 给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价 线性规划的形式: $Min\quad \sum\limits_{i=1}^{m} ...
- [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)
1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 802 Solved: 344[Submit][Sta ...
- 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)
[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...
- 【bzoj1937】 Shoi2004—Mst 最小生成树
http://www.lydsy.com/JudgeOnline/problem.php?id=1937 (题目链接) 题意 一个无向图,给出一个生成树,可以修改每条边的权值,问最小修改多少权值使得给 ...
- 【KM】BZOJ1937 [Shoi2004]Mst 最小生成树
这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. ...
- BZOJ1937 [Shoi2004]Mst 最小生成树
首先由贪心的想法知道,树边只减不加,非树边只加不减,令$w_i$表示i号边原来的边权,$d_i$表示i号边的改变量 对于一条非树边$j$连接着两个点$x$.$y$,则对于$xy$这条路径上的所有树边$ ...
- MST最小生成树
首先,贴上一个很好的讲解贴: http://www.wutianqi.com/?p=3012 HDOJ 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.ph ...
- [poj1679]The Unique MST(最小生成树)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28207 Accepted: 10073 ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
随机推荐
- jquery函数$.proxy简单示例
来自于<jquery 权威指南> ------------------------------ <!DOCTYPE html PUBLIC "-//W3C//DTD XHT ...
- [Jenkins] 执行SoapUI的task,设置邮件内容为HTML+CSS
设置邮件内容:Default Content <span style="font-family:verdana;font-size:16px;color:black;font-weig ...
- Docker 实现的 redis 主从
计划用 Docker 实现 Redis 的主从,简单主从而已.主的名称叫 redis-master 一步步来. 先新建个Dockerfile ,从alpine 开始,比较简单. FROM alpine ...
- 彻底修改Eclipse的默认编码
引用各位前辈经验得到彻底修改eclipse默认编码的方法. 单在eclipse里设置编码方式非常复杂且容易遗漏,全部修改后,有些代码生成模板内的${encode}变量仍为原编码方案,经过查阅许多资料得 ...
- 白盒测试实践项目(day4)
华中科技大学教材订购系统 代码评审会议纪要 与会人员: 胡俊辉.杨瑞丰.汪鸿.张颖.李建文 评审标准: 此次代码评审会议,我们小组选用了阿里巴巴Java开发手册对代码进行评审. 会议过程: 1:周末下 ...
- yii2 Html::a
Html::a($text,$url = null,$options = []) $url 可以直接是字符串 // An empty string. This will return the curr ...
- 用Word 写csdn blog
目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...
- 设计模式11---组合模式(Composite Pattern)
一.组合模式定义 将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性.Compose objects into tree structures to re ...
- linux 进阶2--C++读取lua文件中的变量、一维表、二维表
lua 语言非常灵活,一般把lua 作为脚本文件,会用C++与之进行交互.最重要的是C++代码能读取到脚本中的变量.一维表.二维表. 这样有些参数就可以在lua文件进行更改,而不用重新更改C++代码. ...
- jmeter- 性能测试3:聚合报告(Aggregate Report )
jmeter-监听器-聚合报告样例: 字段说明: label:请求名称,自己定义的 #Samples:这次测试中一共发出了多少个请求,如果模拟20个用户,每个用户迭代20次,那么就是400(未设置持续 ...