【bzoj1937】 Shoi2004—Mst 最小生成树
http://www.lydsy.com/JudgeOnline/problem.php?id=1937 (题目链接)
题意
一个无向图,给出一个生成树,可以修改每条边的权值,问最小修改多少权值使得给出的生成树是最小生成树。
Solution
好神!!!!!
首先,由贪心可知,生成树上的边我们肯定是减小它的权值,非树边我们肯定是增大它的权值。假设树边$i$的权值$w_i$,修改后的权值$w_i-d_i$;非树边$j$的权值$w_j$,修改后的权值$w_j+d_j$。如果$j$有可能代替$i$,那么它们必须满足式子$w_i-d_i<=w_j+d_j$,移下项$w_i-w_j<=d_i+d_j$,是不是很像KM里面的顶标,所以我们把边当做点,边权为两个有制约关系的边的权值差,跑KM求最大权完美匹配就可以了。
纠结了好久,蛋疼死了。我们的确是要求最小的$\sum d_i$,但是$w_i-w_j<=d_i+d_j$的意义是要求对所有的$i,j$都得满足。我们需要在满足条件的情况下不断缩小$\sum d_i$,所以完美匹配以后我们可以使$\sum d_i$最小。
细节
边权非负。可能不会完美匹配,需要加点加边。
代码
// bzoj1937
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf (1ll<<30)
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=1010;
int head[maxn],deep[maxn],vis[maxn],fa[maxn],id[maxn][maxn],n,m,cnt;
int slack[maxn],vx[maxn],vy[maxn],lx[maxn],ly[maxn],p[maxn],mp[maxn][maxn];
struct data {int u,v,w;}a[maxn];
struct edge {int to,next;}e[maxn<<1]; void link(int u,int v) {
e[++cnt]=(edge){v,head[u]};head[u]=cnt;
e[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
void dfs(int x) {
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa[x]) {
deep[e[i].to]=deep[x]+1;
fa[e[i].to]=x;
dfs(e[i].to);
}
}
bool match(int x) {
vx[x]=cnt;
for (int y=1;y<=m;y++) if (vy[y]!=cnt) {
int t=lx[x]+ly[y]-mp[x][y];
if (!t) {
vy[y]=cnt;
if (!p[y] || match(p[y])) {p[y]=x;return 1;}
}
else slack[y]=min(slack[y],t);
}
return 0;
}
int KM() {
for (int i=1;i<=m;i++) {
lx[i]=-inf;
for (int j=1;j<=m;j++) lx[i]=max(lx[i],mp[i][j]);
}
cnt=0;
for (int x=1;x<=m;x++) {
for (int i=1;i<=m;i++) slack[i]=inf;
while (1) {
int d=inf;cnt++;
if (match(x)) break;
for (int i=1;i<=m;i++) if (vy[i]!=cnt) d=min(d,slack[i]);
for (int i=1;i<=m;i++) {
if (vx[i]==cnt) lx[i]-=d;
if (vy[i]==cnt) ly[i]+=d;
}
}
}
int ans=0;
for (int i=1;i<=m;i++) ans+=mp[p[i]][i];
return ans;
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
id[a[i].u][a[i].v]=id[a[i].v][a[i].u]=i;
}
for (int u,v,i=1;i<n;i++) {
scanf("%d%d",&u,&v);
link(u,v);vis[id[u][v]]=1;
}
dfs(1);memset(head,0,sizeof(head));cnt=0;
for (int i=1;i<=m;i++) if (!vis[i]) {
int x=a[i].u,y=a[i].v,w=a[i].w;
if (deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
while (t--) mp[id[x][fa[x]]][i]=max(0,a[id[x][fa[x]]].w-w),x=fa[x];
while (x!=y) {
mp[id[x][fa[x]]][i]=max(0,a[id[x][fa[x]]].w-w);
mp[id[y][fa[y]]][i]=max(0,a[id[y][fa[y]]].w-w);
x=fa[x],y=fa[y];
}
}
printf("%d",KM());
return 0;
}
【bzoj1937】 Shoi2004—Mst 最小生成树的更多相关文章
- [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)
1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 802 Solved: 344[Submit][Sta ...
- 【KM】BZOJ1937 [Shoi2004]Mst 最小生成树
这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. ...
- BZOJ1937 [Shoi2004]Mst 最小生成树
首先由贪心的想法知道,树边只减不加,非树边只加不减,令$w_i$表示i号边原来的边权,$d_i$表示i号边的改变量 对于一条非树边$j$连接着两个点$x$.$y$,则对于$xy$这条路径上的所有树边$ ...
- 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)
[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...
- BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]
传送门 题意: 给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价 线性规划的形式: $Min\quad \sum\limits_{i=1}^{m} ...
- [BZOJ 1937][Shoi2004]Mst 最小生成树
传送门 $ \color{red} {solution:} $ 对于每条树边\(i\),其边权只可能变小,对于非树边\(j\),其边权只可能变大,所以对于任意非树边覆盖的树边有 \(wi - di & ...
- 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个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
随机推荐
- Linux命令对应的英文及整体学习法
linux命令 注意一下内容收集与互联网,如果觉得有版权问题,请联系. 用Linux命令的时候,如果熟悉对应英文的含义,更有助于理解相应的命令.man: Manual 意思是手册,可以用这个命令查询其 ...
- Appium 安装详细版教程
1.安装Appium Python Client包 输入命令 pip install Appium-Python-Client
- 32bit 天堂2 windows 2003 server架设教程
安装环境::[注意:本教程newauth要用不加密的版本] windows 2003 enterprise server 100用户license Microsoft sql server 2000 ...
- 云计算时代,传统企业 IT 从业者如何做好转型?
本文来源于国外社区 DZone,作者 Dennis O'Reilly 撰写过多篇关于云计算.混合云等内容的文章,本文内容围绕云计算时代,企业纷纷上云,传统 IT 从业者如何做好转型. 本文由“数梦工场 ...
- POJ 3164 Sunscreen (挑战程序设计竞赛的练习题)
题目:https://vjudge.net/problem/POJ-3614 思路参考这个:https://blog.csdn.net/qq_25576697/article/details/7657 ...
- 机器学习算法 --- Naive Bayes classifier
一.引言 在开始算法介绍之前,让我们先来思考一个问题,假设今天你准备出去登山,但起床后发现今天早晨的天气是多云,那么你今天是否应该选择出去呢? 你有最近这一个月的天气情况数据如下,请做出判断. 这个月 ...
- 使用cors解决跨域遇到浏览器发出options嗅探
前言: 本地开发起的服务器,通过修改hosts文件设置域名映射到本地,接口在测试环境 1. 服务器端设置cors, 配置access-control-allow-origin 头部 使用蚂蚁金服的up ...
- ES6----Proxy(一)
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. 听起来好像很绕,可以简单这样理解,Proxy相当于 ...
- 20162328蔡文琛 大二week07
20162328 2017-2018-1 <程序设计与数据结构>第7周学习总结 教材学习内容总结 树是非线性结构,其元素组织为一个层次结构. 树的度表示树种任意节点的最大子节点数. 有m个 ...
- 读《我是IT小小鸟》有感
我是一只IT小小鸟,我与IT结缘.书中是作者对个人经历与经验在IT下的体会,却给了我们很好的借鉴. IT这门行业,不仅仅再局限于如我们高中老师教学所要求的内容.IT更加开放,可以通过GitHub.CS ...