题目链接

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

假设要加的边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. Dubbo学习笔记4:服务消费端泛化调用与异步调用

    本文借用dubbo.learn的Dubbo API方式来解释原理. 服务消费端泛化调用 前面我们讲解到,基于Spring和基于Dubbo API方式搭建简单的分布式系统时,服务消费端引入了一个SDK二 ...

  2. bzoj千题计划247:bzoj4903: [Ctsc2017]吉夫特

    http://uoj.ac/problem/300 预备知识: C(n,m)是奇数的充要条件是 n&m==m 由卢卡斯定理可以推出 选出的任意相邻两个数a,b 的组合数计算C(a,b)必须是奇 ...

  3. [软件]在浏览器里添加MarkDown Here(插件)

    1. 先来说说这个插件的作用是什么: 用于在网页一些编辑文本的地方, 使用MacDown编辑文本 支持大部分浏览器,  https://github.com/adam-p/markdown-here ...

  4. WebSlides - 轻松制作漂亮的 HTML 幻灯片(演讲稿)

    WebSlides 是一个开源的 HTML 幻灯片项目,能够帮助熟悉前端语言的开发者快速制作出效果精美的幻灯片.页面中的每个 <section> 都是一个独立的幻灯片,只需要很少的 CSS ...

  5. HDU 1241 Oil Deposits DFS搜索题

    题目大意:给你一个m*n的矩阵,里面有两种符号,一种是 @ 表示这个位置有油田,另一种是 * 表示这个位置没有油田,现在规定相邻的任意块油田只算一块油田,这里的相邻包括上下左右以及斜的的四个方向相邻的 ...

  6. 第10月第13天 xcode ipa

    1. xcodebuild -exportArchive -exportFormat ipa -archivePath RongChatRoomDemo\ 17-7-13\ 下午4.04.xcarch ...

  7. CF359B Permutation (构造)

    CF359B Permutation \(solution:\) 作为一道构造题,这题也十分符合构造的一些通性----(找到一些规律,然后无脑循环). 构造一个长度为 \(2n\) 的排列 \(a\) ...

  8. linux 串口驱动(二)初始化 【转】

    转自:http://blog.chinaunix.net/uid-27717694-id-3493611.html 8250串口的初始化: (1)定义uart_driver.uart_ops.uart ...

  9. Flask源码解析:Flask应用执行流程及原理

    WSGI WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述服务器端如何与web应用程序通信的 ...

  10. 解除IIS配置节锁定

    C:\windows\system32\inetsrv\appcmd unlock config -section:system.webServer/modules