2521: [Shoi2010]最小生成树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 445  Solved: 262
[Submit][Status][Discuss]

Description

Secsa最近对最小生成树问题特别感兴趣。他已经知道如果要去求出一个n个点、m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法。另外,他还知道,某一个图可能有多种不同的最小生成树。例如,下面图 3中所示的都是图 2中的无向图的最小生成树:
 
 

当然啦,这些都不是今天需要你解决的问题。Secsa想知道对于某一条无向图中的边AB,至少需要多少代价可以保证AB边在这个无向图的最小生成树中。为了使得AB边一定在最小生成树中,你可以对这个无向图进行操作,一次单独的操作是指:先选择一条图中的边 P1P2,再把图中除了这条边以外的边,每一条的权值都减少1。如图 4所示就是一次这样的操作:

Input

输入文件的第一行有3个正整数n、m、Lab分别表示无向图中的点数、边数、必须要在最小生成树中出现的AB边的标号。
接下来m行依次描述标号为1,2,3…m的无向边,每行描述一条边。每个描述包含3个整数x、y、d,表示这条边连接着标号为x、y的点,且这条边的权值为d。
输入文件保证1<=x,y<=N,x不等于y,且输入数据保证这个无向图一定是一个连通图。

Output

输出文件只有一行,这行只有一个整数,即,使得标号为Lab边一定出现最小生成树中的最少操作次数。

Sample Input

4 6 1
1 2 2
1 3 2
1 4 3
2 3 2
2 4 4
3 4 5

Sample Output

1

HINT

第1个样例就是问题描述中的例子。

1<=n<=500,1<=M<=800,1<=D<10^6

Source

[Submit][Status][Discuss]

题目中的操作——将除这条边外所有其他边的权值全部+1——就是忽悠人的,等价于将这条边的权值+1。

利用Kruskal算法的思想,如果将所有边按照权值从小到大排序后,排在指定边之前(包括和指定边权值相同)的边能使得指定边的两点联通,则指定边一定不会被选中。将一条边从指定边之前移走的最小代价就是使得其变得严格大于指定边,插值是$Val_{id}-Val_{i}+1$。把代价作为容量,跑最小割即可。

 #include <cstdio>
#include <cstring> inline char nextChar(void)
{
static const int siz = << ; static char buf[siz];
static char *hd = buf + siz;
static char *tl = buf + siz; if (hd == tl)
fread(hd = buf, , siz, stdin); return *hd++;
} inline int nextInt(void)
{
register int ret = ;
register bool neg = false;
register char bit = nextChar(); for (; bit < ; bit = nextChar());
if (bit == '-')neg ^= true; for (; bit > ; bit = nextChar())
ret = ret * + bit - ''; return neg ? -ret : ret;
} const int siz = ;
const int edg = 2e6 + ;
const int inf = 2e9 + ; int n, m, id, s, t; struct edge
{
int x, y, w;
}e[edg]; int hd[siz], to[edg], nt[edg], fl[edg], tot; inline void add(int u, int v, int f)
{
nt[tot] = hd[u]; to[tot] = v; fl[tot] = f; hd[u] = tot++;
nt[tot] = hd[v]; to[tot] = u; fl[tot] = ; hd[v] = tot++;
} int dep[siz]; inline bool bfs(void)
{
static int que[siz];
static int head, tail; memset(dep, , sizeof(dep)); que[head = ] = s, tail = dep[s] = ; while (head != tail)
{
int u = que[head++], v; for (int i = hd[u]; ~i; i = nt[i])
if (!dep[v = to[i]] && fl[i])
dep[que[tail++] = v] = dep[u] + ;
} return dep[t];
} int cur[siz]; inline int min(int a, int b)
{
return a < b ? a : b;
} int dfs(int u, int f)
{
if (!f || u == t)
return f; int used = , flow, v; for (int i = cur[u]; ~i; i = nt[i])
if (dep[v = to[i]] == dep[u] + && fl[i])
{
flow = dfs(v, min(fl[i], f - used)); used += flow;
fl[i] -= flow;
fl[i^] += flow; if (fl[i])
cur[u] = i; if (used == f)
return f;
} if (!used)
dep[u] = ; return used;
} inline int minCut(void)
{
int minCut = , newFlow; while (bfs())
{
memcpy(cur, hd, sizeof(hd)); while (newFlow = dfs(s, inf))
minCut += newFlow;
} return minCut;
} signed main(void)
{
n = nextInt();
m = nextInt(); id = nextInt(); for (int i = ; i <= m; ++i)
{
e[i].x = nextInt();
e[i].y = nextInt();
e[i].w = nextInt();
} s = e[id].x;
t = e[id].y; int lim = e[id].w; memset(hd, -, sizeof(hd)); for (int i = ; i <= m; ++i)
if (e[i].w <= lim && i != id)
add(e[i].x, e[i].y, lim + - e[i].w),
add(e[i].y, e[i].x, lim + - e[i].w); printf("%d\n", minCut());
}

@Author: YouSiki

BZOJ 2521: [Shoi2010]最小生成树的更多相关文章

  1. BZOJ 2521: [Shoi2010]最小生成树(最小割)

    题意 对于某一条无向图中的指定边 \((a, b)\) , 求出至少需要多少次操作.可以保证 \((a, b)\) 边在这个无向图的最小生成树中. 一次操作指: 先选择一条图中的边 \((u, v)\ ...

  2. BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)

    题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...

  3. 【BZOJ2521】[Shoi2010]最小生成树 最小割

    [BZOJ2521][Shoi2010]最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算 ...

  4. bzoj2521 [Shoi2010]最小生成树

    [Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MB Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出 ...

  5. BZOJ 2521 最小生成树(最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2521 题意:每次能增加一条边的权值1,求最小代价让一条边保证在最小生成树里 思路:如果两个点中有环, ...

  6. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

  7. BZOJ 2177: 曼哈顿最小生成树

    Sol 考了好几次曼哈顿最小生成树,然而一直不会打...这次终于打出来了...神tm调试了2h...好蛋疼... 首先曼哈顿最小生成树有个结论就是讲它每45度分出一个象限,对于每个点,只与每个象限中离 ...

  8. BZOJ 3732: Network 最小生成树 倍增

    3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...

  9. [BZOJ]1016 JSOI2008 最小生成树计数

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

随机推荐

  1. [转载]使用mpvue搭建一个初始小程序

    1. 初始化一个 mpvue 项目 现代前端开发框架和环境都是需要 Node.js 的,如果没有的话,请先下载 nodejs 并安装. 然后打开命令行工具: # 1. 先检查下 Node.js 是否安 ...

  2. Netty源码分析第4章(pipeline)---->第4节: 传播inbound事件

    Netty源码分析第四章: pipeline 第四节: 传播inbound事件 有关于inbound事件, 在概述中做过简单的介绍, 就是以自己为基准, 流向自己的事件, 比如最常见的channelR ...

  3. C#中字符串 "驻留"与Lock(转载)

    class TestWorker 2 {         3     public void DoMultiThreadedWork(object someParameter) 4     { 5   ...

  4. python-模拟掷骰子,两个筛子数据可视化

    """ 作者:zxj 功能:模拟掷骰子,两个筛子数据可视化 版本:3.0 日期:19/3/24 """ import random impo ...

  5. shell之arp命令

    arp: 显示所有的表项. arp -d address: 删除一个arp表项. arp -s address hw_addr: 设置一个arp表项.   常用参数: -a 使用bsd形式输出.(没有 ...

  6. 用C给小学生出题目

    用C给小学生出题目 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 600 300 • Es ...

  7. matconvnet编译

    1.安装matconvnet 网上教程很多 2.编译 cd matconvnet/ addpath matlab/ vl_compilenn('enableGpu',true,'cudaRoot',' ...

  8. Teamwork(The sixth day of the team)

    每日列会过后,我们的工作进度都有所进展了,好开心,但是还不是我们想要的,我们想做得更快,更好.

  9. 简单实现wc.exe软件基本功能

    简单实现wc.exe软件基本功能 软件需求分析: 一.基本功能 支持 -c  统计字符数(char count) 支持 -w  统计单词数(word count) 支持 -l  统计总行数(line ...

  10. 封装GetQueryString()方法来获取URL的value值(转载)

    首先测试URL:http://192.168.1.82:8020/juzhong/daojishi.html?name=xiangruding&sex=nuuu&age=90 代码如下 ...