初看题目,发现题目的操作比较复杂。仔细想了一想,发现题目中的操作“把图中除了这条边以外的边,每一条的权值都减少 1 1 1”就等价于“把这条边的权值加 1 1 1”。所以题目的操作就被我们化繁为简了。

然后继续想:如何才能使 L a b Lab Lab 边一定在最小生成树中?

画个图看一下(就以样例为例):

假设现在 L a b Lab Lab 边是 ( 1 , 2 ) (1,2) (1,2),长度为 2 2 2。

那么既然我要保证 L a b Lab Lab 边是最小生成树的一条边,点 1 1 1、 2 2 2 就不能在一个环里面,也就是说,点 1 1 1、 2 2 2 之间不能存在另一条可选的路径。(注意“边”与“路径”的区别)

也就是说,在原来的无向图上, 1 → 2 1\rightarrow2 1→2 的其他路径中,每条路径至少要存在一条边的边权大于 2 2 2,否则在建最小生成树时就有可能被选到。

比如 1 → 2 1\rightarrow2 1→2 的其他路径有 1 → 3 → 2 1\rightarrow3\rightarrow2 1→3→2、 1 → 4 → 2 1\rightarrow4\rightarrow2 1→4→2 ……,其中路径 1 → 3 → 2 1\rightarrow3\rightarrow2 1→3→2 是不满足条件的,因为这条路径上没有一条边的边权大于 2 2 2,那么我们就有可能选边:

而不是这样:

总而言之,设 L a b Lab Lab 边是 ( A , B ) (A,B) (A,B),长度为 l e n len len,那么我们要保证在操作之后的无向图上,不存在一条路径 A → B A\rightarrow B A→B 使得这条路径上所有边的边权都小于等于 l e n len len。

如何维护?

一种显然的暴力就是:枚举 A → B A\rightarrow B A→B 的每一条路径,找到路径上边权的最大值 m a x n maxn maxn,如果 m a x n > l e n maxn>len maxn>len,就不管它,否则就用 l e n − m a x n + 1 len-maxn+1 len−maxn+1 次操作使得这条边权最大的边的权值加上 l e n − m a x n + 1 len-maxn+1 len−maxn+1,超过 l e n len len。这时我们就能用最小的代价保证这条路径不可能被选到。

想到这里很容易想到最小割:找到边权 l e n 0 len_0 len0​ 小于等于 l e n len len 的每条边 ( u , v ) (u,v) (u,v),并在另一个图上建边 ( u , v , l e n − l e n 0 + 1 ) (u,v,len-len_0+1) (u,v,len−len0​+1),然后再从 A A A 到 B B B 跑最小割,也就是说找到 A → B A\rightarrow B A→B 每条路径上操作代价最小的一条边。最后跑出来的最小割就是答案。

代码如下:

#include<bits/stdc++.h>#define N 510
#define M 810
#define INF 0x7fffffffusing namespace std;struct edge
{int u,v,w;
}e[M];int n,m,lab,s,t;
int cnt=1,head[N],cur[N],to[M<<2],nxt[M<<2],c[M<<2];
int num[N];queue<int>q;void adde(int u,int v,int ci)
{to[++cnt]=v;c[cnt]=ci;nxt[cnt]=head[u];head[u]=cnt;to[++cnt]=u;c[cnt]=0;nxt[cnt]=head[v];head[v]=cnt;
}bool bfs()
{memcpy(cur,head,sizeof(cur));memset(num,-1,sizeof(num));q.push(s);num[s]=0;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i;i=nxt[i]){int v=to[i];if(c[i]&&num[v]==-1){num[v]=num[u]+1;q.push(v);}}}return num[t]!=-1;
}int dfs(int u,int minflow)
{if(!minflow||u==t) return minflow;int preflow=0,nowflow;for(int i=cur[u];i;i=nxt[i]){cur[u]=i;int v=to[i];if(num[v]==num[u]+1&&(nowflow=dfs(v,min(minflow-preflow,c[i])))){preflow+=nowflow;c[i]-=nowflow;c[i^1]+=nowflow;if(!(minflow-preflow)) break;}}return preflow;
}int dinic()
{int maxflow=0;while(bfs())maxflow+=dfs(s,INF);return maxflow;
}int main()
{scanf("%d%d%d",&n,&m,&lab);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);s=e[lab].u,t=e[lab].v;for(int i=1;i<=m;i++){if(i!=lab&&e[i].w<=e[lab].w){adde(e[i].u,e[i].v,e[lab].w-e[i].w+1);//别问我为什么要建双向边,问就是这是dinic,分层图不怕死循环adde(e[i].v,e[i].u,e[lab].w-e[i].w+1);}}printf("%d\n",dinic());return 0;
}

【SHOI2010】最小生成树(最小割,最小生成树)相关推荐

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

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

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

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

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

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

  4. 【bzoj2521】[Shoi2010]最小生成树 网络流最小割

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

  5. P5934-[清华集训2012]最小生成树【最小割】

    正题 题目链接:https://www.luogu.com.cn/problem/P5934 题目大意 给出nnn个点mmm条边的一张图,再加入一条边(u,v,L)(u,v,L)(u,v,L)求至少删 ...

  6. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

  7. [学习笔记]最小割之最小点权覆盖最大点权独立集

    最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...

  8. POJ 1966 Cable TV Network【无向图点连通度 最小割 E-K算法求最大流】

    题目描述: 给你一个无向图,问你最少删掉几个点,使这个图成不连通. 解题报告: 概念 (1)一个具有 N 个顶点的图,在去掉任意 k-1 个顶点后 (1<=K<=N) 所得的子图仍连通, ...

  9. 最小割 ---- 2021 ccpc 威海 H city-safety(最大利润 = 最大收益 - 最小花费(最小割))

    题目链接 题目大意: 一棵树,加强第 iii 个点有 wiw_iwi​ 的花费,而如果距离某 个点 ≤p≤ p≤p 的所有点都加强了,则会有 vpv_pvp​ 的收益,求最大净收益. 解题思路: 树形 ...

最新文章

  1. 使用getopt处理shell脚本的参数
  2. spring-MVC源码解读(一)
  3. 计算机网络核心知识(上)
  4. ajax php 观察者模式,JavaScript观察者模式定义和dom事件实例详解
  5. 汇编语言---计算有符号数算式的值
  6. 史上最详 Thymeleaf 使用教程
  7. mybatis SqlMapConfig.xml environments
  8. Kubernetes学习之路(26)之kubeasz+ansible部署集群
  9. Linux基础-1.Linux命令及获取帮助
  10. 1043 : 最大值
  11. 什么是服务器安全性?
  12. Java SE到Java EE的学习转换
  13. WebDriverPool浏览器驱动池 减少驱动频繁打开和关闭引起的资源损耗
  14. max2 android9.0,乐视max2 安卓9.0刷机包
  15. python控制手机
  16. font-awesome样式只显示方框
  17. AI耳机要想“复制”智能音箱的爆红,还要迈过哪些坎?
  18. NCBI数据下载-sra
  19. 净亏10.89亿欧元!法雷奥:2021年仍需保持谨慎,ADAS业务表现最佳
  20. 【AI简报20210910期】联想发布LA2智能嵌入式控制器、单目摄像头实时感知车辆形状...

热门文章

  1. 系统服务器节能,解析服务器的三大节能技术
  2. Redis分布式锁的原理、作用及实现(简单易懂)
  3. HEC-RAS数值模拟与GIS水文分析技术的洪水危险性及风险评估
  4. 定位修改器服务器错误是什么意思,定位修改器提示程序出错怎么处理
  5. ECS(centos7)安装erlang再安装rabbitmq报错erlang >= 23.2 is needed by rabbitmq-server-3.9.5-1.el7.noarch
  6. 红米手机使用应用沙盒动态修改位置数据
  7. Python列表使用
  8. Excel表格如何转换成pdf格式
  9. 2019年营销经典案例
  10. 告别单身+成就霸业,男人们必知的人生定律