传送门

$ \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 最小生成树的更多相关文章

  1. BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]

    传送门 题意: 给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价 线性规划的形式: $Min\quad \sum\limits_{i=1}^{m} ...

  2. [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)

    1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 802  Solved: 344[Submit][Sta ...

  3. 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)

    [BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...

  4. 【bzoj1937】 Shoi2004—Mst 最小生成树

    http://www.lydsy.com/JudgeOnline/problem.php?id=1937 (题目链接) 题意 一个无向图,给出一个生成树,可以修改每条边的权值,问最小修改多少权值使得给 ...

  5. 【KM】BZOJ1937 [Shoi2004]Mst 最小生成树

    这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. ...

  6. BZOJ1937 [Shoi2004]Mst 最小生成树

    首先由贪心的想法知道,树边只减不加,非树边只加不减,令$w_i$表示i号边原来的边权,$d_i$表示i号边的改变量 对于一条非树边$j$连接着两个点$x$.$y$,则对于$xy$这条路径上的所有树边$ ...

  7. MST最小生成树

    首先,贴上一个很好的讲解贴: http://www.wutianqi.com/?p=3012 HDOJ 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.ph ...

  8. [poj1679]The Unique MST(最小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28207   Accepted: 10073 ...

  9. UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

    题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...

随机推荐

  1. C#中一个窗口是一个类呢,还是一个窗口类的实例呢?(转)

    C#中一个窗口是一个类呢,还是一个窗口类的实例呢? 答: 没有一个人说到重点上. 一个窗口,它不是仅仅用一个类可以描述的: 首先,这个窗口的数据类型类型,是从Form类派生下来的,也就是说它的定义是一 ...

  2. [SoapUI] 在某个测试步骤下面增加Script Assertion,运用 messageExchange 获取response content

    import com.eviware.soapui.support.GroovyUtils import com.eviware.soapui.support.XmlHolder import org ...

  3. Notepad++ xml/json格式化

    Xml格式化: 1. 安装XML Tools插件 (1) 通过网址http://sourceforge.net/projects/npp-plugins/files/XML%20Tools/下载XML ...

  4. CSS选择器种类及介绍

    首先说主都有哪些先择器 1.标签选择器(如:body,div,p,ul,li) 2.类选择器(如:class="head",class="head_logo") ...

  5. Web实践—Rec 1

    累计完成任务情况: 阶段内容 参与人 开会学习作业要求,取得共识 全体 注: 1."阶段内容"划斜线表示完成.2.采用倒序. 具体情况: 正式开展实践作业之前的说明: 按照之前达成 ...

  6. 将windows上面的项目拷贝到Linux环境下报错不能够找到对应的表com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'puyang.ServiceType' doesn't exist

    将一模一样的项目从win迁移到到linux上报错: 一开始还是以为是linux不能识别hql语句,查找资料发现是因为Liunx服务器上mysql是区分大小写的,而本地是不区分的如:代码是这样写的 @E ...

  7. HTML inline 与block元素

    行标签:内容撑开宽度,不可以控制宽和高,它的宽和高随标签里的内容而改变 块标签:撑满行(默认) ,可以用样式控制其宽和高 但行标签 img,textarea,select,input 是可以设置宽和高 ...

  8. 12306GT多线程、分流免费抢票工具使用心德

    大事记背景 我相信很多远游他乡的朋友每逢佳节都会遇到一个难题,就是购票难,这个难题有多难呢?经常在12306官网购票的小伙伴应该知道每个地方的放票时间是不一样的,但是逢年过节的那几天即使你在放票几分钟 ...

  9. 响应者链条,iOS中touchs事件的处理流程。

    用户在使用app的时候,会产生各样的事件.在iOS中的事件可以分为三种 触摸事件(Touch Event) 加速计事件(Accelerometer Event) 远程控制事件(Remote Contr ...

  10. Android-Style样式

    说到Style样式在,HTML+Javascript+CSS中,CSS就是样式,样式可以把很多通用到效果,统一为一个样式,达到通用的目的,也可以让代码更加简洁. 什么时候用Style样式 ? 例如:A ...