题目链接

一条边不变其它边减少可以看做一条边增加其它边不变。

假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通A,B时(即Kruskal中Union())才一定会选择这条边。

要求路径上最小边的权值\(>v\),即要求在路径上有任意一边权值\(\leq v\)时不连通。于是求最小割(使它不连通),割掉一条边的代价即\(v[lab]-v[i]+1\)。

无向图建双向边。

status里的怎么都那么快?复制了一份20的也60+

ISAP:

//892kb	64ms
//ISAP lev[]的上限是n不是des。。
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=505,M=3215; int n,m,lab,s[805],t[805],v[805];
int src,des,Enum,cur[N],H[N],nxt[M],fr[M],to[M],cap[M],pre[N],lev[N],que[N],num[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v,int w)
{
to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
bool BFS()
{
for(int i=1; i<=n; ++i) lev[i]=n+1;
lev[des]=0, que[0]=des; int h=0,t=1;
while(h<t)
{
int x=que[h++];
for(int i=H[x]; i; i=nxt[i])
if(lev[to[i]]==n+1 && cap[i^1])
lev[to[i]]=lev[x]+1, que[t++]=to[i];
}
return lev[src]<=n;
}
int Augment()
{
int mn=1e9;
for(int i=des; i!=src; i=fr[pre[i]])
mn=std::min(mn,cap[pre[i]]);
for(int i=des; i!=src; i=fr[pre[i]])
cap[pre[i]]-=mn, cap[pre[i]^1]+=mn;
return mn;
}
int ISAP()
{
if(!BFS()) return 0;
for(int i=1; i<=n; ++i) ++num[lev[i]],cur[i]=H[i];
int x=src,res=0;
while(lev[src]<=n)
{
if(x==des) x=src,res+=Augment();
bool can=0;
for(int i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]-1 && cap[i])
{
can=1, cur[x]=i, pre[x=to[i]]=i;
break;
}
if(!can)
{
int mn=n;
for(int i=H[x]; i; i=nxt[i])
if(cap[i]) mn=std::min(mn,lev[to[i]]);
if(!--num[lev[x]]) break;
++num[lev[x]=mn+1], cur[x]=H[x];
if(x!=src) x=fr[pre[x]];
}
}
return res;
} int main()
{
n=read(),m=read(),lab=read(),Enum=1;
for(int i=1; i<=m; ++i) s[i]=read(),t[i]=read(),v[i]=read();
src=s[lab], des=t[lab];
for(int i=1; i<=m; ++i)
if(i!=lab&&v[i]<=v[lab]) AddEdge(s[i],t[i],v[lab]-v[i]+1),AddEdge(t[i],s[i],v[lab]-v[i]+1);
printf("%d",ISAP()); return 0;
}

Dinic:

//876kb	60ms 果然差不多
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=505,M=3215; int n,m,lab,s[805],t[805],v[805];
int src,des,Enum,cur[N],H[N],nxt[M],to[M],cap[M],lev[N],que[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v,int w)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
bool BFS()
{
for(int i=1; i<=n; ++i) lev[i]=0,cur[i]=H[i];
lev[src]=1, que[0]=src; int h=0,t=1;
while(h<t)
{
int x=que[h++];
for(int i=H[x]; i; i=nxt[i])
if(!lev[to[i]] && cap[i])
{
lev[to[i]]=lev[x]+1, que[t++]=to[i];
if(to[i]==des) return 1;
}
}
return 0;
}
int Dinic(int x,int flow)
{
if(x==des) return flow;
int used(0);
for(int &i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]+1&&cap[i])
{
int delta=Dinic(to[i],std::min(flow-used,cap[i]));
if(delta)
{
cap[i]-=delta, cap[i^1]+=delta;
if((used+=delta)==flow) return flow;
}
}
lev[x]=0;
return used;
} int main()
{
n=read(),m=read(),lab=read(),Enum=1;
for(int i=1; i<=m; ++i) s[i]=read(),t[i]=read(),v[i]=read();
src=s[lab], des=t[lab];
for(int i=1; i<=m; ++i)
if(i!=lab&&v[i]<=v[lab]) AddEdge(s[i],t[i],v[lab]-v[i]+1),AddEdge(t[i],s[i],v[lab]-v[i]+1);
int res=0;
while(BFS()) res+=Dinic(src,1e9);
printf("%d",res); return 0;
}

BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)的更多相关文章

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

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 445  Solved: 262[Submit][Statu ...

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

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

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

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

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

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

  5. BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)

    BZOJ 洛谷 \(LIS\)..经典模型? 令\(f_i\)表示以\(i\)结尾的\(LIS\)长度. 如果\(f_i=1\),连边\((S,i,INF)\):如果\(f_i=\max\limits ...

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

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

  7. 【BZOJ-2521】最小生成树 最小割

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 415  Solved: 242[Submit][Statu ...

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

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

  9. bzoj 2127 happiness【最小割+dinic】

    参考:https://www.cnblogs.com/chenyushuo/p/5144957.html 不得不说这个建图方法真是非常妙啊 假设S点选理,T点选文,a[i][j]为(i,j)选文收益, ...

随机推荐

  1. Pycharm使用详解

    Pycharm使用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 古人云,工欲善其事,必先利其器.想要学好Python且拥有高效的开发效率,这个时候每个程序员都有自己的开发方式 ...

  2. SHELL (3) —— 变量知识进阶和实践

    摘自:Oldboy Linux运维——SHELL编程实战 SHELL中特殊切重要的变量 位置变量 作用说明 $0 获取当前执行的Shell脚本的文件名,如果执行脚本包含了路径,那么就包括脚本路径 $n ...

  3. c#的事件用法——实现下载时发生的事件

    //下载时发出的事件 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...

  4. github 远程仓库

    因为本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以设置一下 第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_r ...

  5. MySQL索引背后的数据结构及算法原理 (转)

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  6. 叉积(POJ - 2318 )

    题目链接:https://cn.vjudge.net/contest/276358#problem/A 题目大意:给你一个矩阵的左上角和右下角,然后n个竖杠,这n个竖杠将这个矩阵分成n+1个方块,给你 ...

  7. [转]避免头文件重复包含以及#ifndef 与 #program once 的区别

    为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式.在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一 ...

  8. 常用SQL函数(字符串分隔转表、自增长转编号)

    字符串分隔转表 -- ============================================= -- Author: -- Create date: -- Description: ...

  9. findHomography和perspectiveTransform

    opencv中的两个函数,之前一直不明白这俩函数到底是要干嘛的. 得到两帧图像中的特征点后,就可以用findHomography得到单应性矩阵. 得到单应性矩阵后,可以 (1)根据相应的计算方法,由前 ...

  10. Codeforces 671A Recycling Bottles(贪心+思维)

    题目链接:http://codeforces.com/problemset/problem/671/A 题目大意:给你两个人的位置和一个箱子的位置,然后给出n个瓶子的位置,要求让至少一个人去捡瓶子放到 ...