2521: [Shoi2010]最小生成树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 415  Solved: 242
[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

day2

Solution

水题

首先考虑,选择一条边不变,其余边权-1;显然就相当于,选择一条边权+1,其余边不变

要求选定边id一定在最小生成树上,考虑一下求最小生成树的过程Kruskal

显然对这条边有影响的边是初始边权比他小的边,若id边一定加入到最小生成树中,也就是说,边权<=val[id]的边中,不存在能使x[id],y[id]的联通的边

那么对于一条边x,使他不对id产生影响的最小代价是val[id]+1-val[x](使他边权变成恰大于id边权)

那么显然最小化代价,用最小割处理即可

把初始边权小于等于id的边相连,约束为val[id]+1-val[x],然后跑x[id]到y[id]的最小割即可

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
void Freopen () {freopen("build.in","r",stdin); freopen("build.out","w",stdout);}
void Fclose() {fclose(stdin); fclose(stdout);}
#define MAXM 1000010
#define MAXN 1010
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int N,M,id;
struct RoadNode{int u,v,w,id;}road[MAXM];
struct EdgeNode{int next,to,cap;}edge[MAXM<<];
int head[MAXN],cnt=;
void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w;}
void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,);}
int h[MAXN],cur[MAXN],S,T;
bool BFS()
{
queue<int>q;
for (int i=S; i<=T; i++) h[i]=-;
q.push(S); h[S]=;
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==-)
h[edge[i].to]=h[now]+,q.push(edge[i].to);
}
return h[T]!=-;
}
int DFS(int loc,int low)
{
if (loc==T) return low;
int used=,w;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==h[loc]+)
{
w=DFS(edge[i].to,min(edge[i].cap,low-used));
edge[i].cap-=w,edge[i^].cap+=w; used+=w;
if (edge[i].cap) cur[loc]=i;
if (used==low) return low;
}
if (!used) h[loc]=-;
return used;
}
#define INF 0x7fffffff
int Dinic()
{
int re=;
while (BFS())
{
for (int i=S; i<=T; i++) cur[i]=head[i];
re+=DFS(S,INF);
}
return re;
}
int D;
void BuildGraph()
{
S=,T=N+;
for (int i=; i<=M; i++)
if (road[i].w<=D)
{
if (road[i].id!=id)
InsertEdge(road[i].u,road[i].v,D+-road[i].w),
InsertEdge(road[i].v,road[i].u,D+-road[i].w);
else InsertEdge(S,road[i].u,INF),InsertEdge(road[i].v,T,INF);
}
else break;
}
bool cmp(RoadNode A,RoadNode B) {return A.w<B.w;}
int main()
{
N=read(),M=read(),id=read();
for (int i=; i<=M; i++)
road[i].u=read(),road[i].v=read(),road[i].w=read(),road[i].id=i;
D=road[id].w;
sort(road+,road+M+,cmp);
BuildGraph();
printf("%d\n",Dinic());
return ;
}

【BZOJ-2521】最小生成树 最小割的更多相关文章

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

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

  2. BZOJ 2561: 最小生成树(最小割)

    U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...

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

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

  4. BZOJ2521:[SHOI2010]最小生成树(最小割)

    Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...

  5. BZOJ2561最小生成树——最小割

    题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...

  6. BZOJ2521[Shoi2010]最小生成树——最小割

    题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...

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

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

  8. 【BZOJ2561】最小生成树 最小割

    [BZOJ2561]最小生成树 Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在 ...

  9. spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】

    因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...

随机推荐

  1. 解决编译apache出现的问题:configure: error: APR not found . Please read the documentation

    今日编译apache时出错: #./configure --prefix……检查编辑环境时出现: checking for APR... no configure: error: APR not fo ...

  2. openwrt编译出错处理记录

    1.代码从windows复制过来编译报错处理,参考:http://www.360doc.com/content/13/1016/21/3884271_321966616.shtml 2.编译lua-s ...

  3. lecture2-NN结构的主要类型的概述和感知机

    Hinton课程第二课 一.NN结构的主要类型的概述 这里的结构就是连接在一起的神经元.目前来说,在实际应用中最常见的NN就是前向NN,他是将数据传递给输入单元,通过隐藏层最后到输出层的单元:一个更有 ...

  4. WPFProgressBarAndSlider随位置显示Value

    先来一发图,有图有真相. 核心代码如下 ProgressBar添加一个textBlock 绑定Value并且位置绑定进度条的实际宽度 <Canvas Height="10" ...

  5. (十七)迭代器模式详解(foreach的精髓)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和 ...

  6. 文本 To 音频

    文本  To  音频 TextToSpeech介绍 TextToSpeech,简称 TTS,是Android 1.6版本中比较重要的新功能.将所指定的文本转成不同语言音频输出.它可以方便的嵌入到游戏或 ...

  7. 匈牙利算法(codevs2776)

    type node=^link; link=record des:longint; next:node; end; var n,m,i,t,num:longint; p:node; nd:..] of ...

  8. Linux 配置只安装 64 位软件包

    Centos.RHEL等系统,yum 安装的时候有时候会安装32的,然而我们只需要安装64位的软件! 解决方法: yum只安装 64 位的包,只需在 /etc/yum.conf 中加入 "e ...

  9. Ceph Zabbix plugin 插件和模板

    由于Ceph项目中的 Celemeter 缺乏告警功能和监控平台的统一性要求, YY 云平台Ceph集群的监控需求,都是在团队已有的zabbix平台基础上开发完成的. 在已有的git开源项目基础上做了 ...

  10. 开发错误日记 12: Unsupported major.minor version 52.0

    开发错误日记 12: Unsupported major.minor version 52.0 在编译时出现如下错误: java.lang.UnsupportedClassVersionError: ...