BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解)
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1628 Solved: 786
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2561
Description
给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多少条边,才能够使得这条边既可能出现在最小生成树上,也可能出现在最大生成树上?
Input
接下来M行,每行包含三个正整数u,v和w表示图G存在一条边权为w的边(u,v)。
最后一行包含用空格隔开的三个整数,分别为u,v,和 L;
数据保证图中没有自环。
Output
输出一行一个整数表示最少需要删掉的边的数量。
Sample Input
3 2 1
1 2 3
1 2 2
Sample Output
HINT
对于20%的数据满足N ≤ 10,M ≤ 20,L ≤ 20;
对于50%的数据满足N ≤ 300,M ≤ 3000,L ≤ 200;
对于100%的数据满足N ≤ 20000,M ≤ 200000,L ≤ 20000。
- #include<iostream>
- #include<fstream>
- #include<cstdio>
- #include<algorithm>
- #include<string>
- #include<vector>
- #include<queue>
- #include<deque>
- #include<utility>
- #include<map>
- #include<set>
- #include<cmath>
- #include<cstdlib>
- #include<ctime>
- #include<functional>
- #include<sstream>
- #include<cstring>
- #include<bitset>
- #include<stack>
- using namespace std;
- int n,m,s,t,cnt,x,y,z,ansx,l;
- struct sdt
- {
- int cap,flow,u,v;
- }e[400005];
- struct bdq
- {
- int a,b,c;
- }edge[200005];
- int nxt[400005],fir[20005],d[20005],par[20005],num[20005],cur[20005];
- bool vis[20005];
- int read()
- {
- int x=0;char c=getchar();
- while(c<48||c>57)c=getchar();
- while(c>47&&c<58)x*=10,x+=c-48,c=getchar();
- return x;
- }
- void bfs()
- {
- memset(vis,0,sizeof(vis));
- memset(d,0,sizeof(d));
- queue<int>q;
- d[t]=0;
- vis[t]=1;
- q.push(t);
- while(!q.empty())
- {
- int k=q.front();
- q.pop();
- for(int i=fir[k];i;i=nxt[i])
- {
- if(!vis[e[i].v])
- {
- vis[e[i].v]=1;
- d[e[i].v]=d[k]+1;
- q.push(e[i].v);
- }
- }
- }
- }
- int agument()
- {
- int p=t;
- int ans=2147483647;
- while(p!=s)
- {
- ans=min(ans,e[par[p]].cap-e[par[p]].flow);
- p=e[par[p]].u;
- }
- p=t;
- while(p!=s)
- {
- e[par[p]].flow+=ans;
- e[par[p]^1].flow-=ans;
- p=e[par[p]].u;
- }
- return ans;
- }
- int isap()
- {
- memset(num,0,sizeof(num));
- int flow=0;
- for(int i=1;i<=n;i++)
- {
- num[d[i]]++;
- cur[i]=fir[i];
- }
- int p=s;
- while(d[s]<n)
- {
- if(p==t)
- {
- flow+=agument();
- p=s;
- }
- bool ok=0;
- for(int i=cur[p];i;i=nxt[i])
- {
- if(e[i].cap>e[i].flow && d[p]==d[e[i].v]+1)
- {
- ok=1;
- par[e[i].v]=i;
- cur[p]=i;
- p=e[i].v;
- break;
- }
- }
- if(!ok)
- {
- int mn=n-1;
- for(int i=fir[p];i;i=nxt[i])
- {
- if(e[i].cap>e[i].flow)mn=min(mn,d[e[i].v]);
- }
- if(--num[d[p]]==0)break;
- num[d[p]=mn+1]++;
- cur[p]=fir[p];
- if(p!=s)p=e[par[p]].u;
- }
- }
- return flow;
- }
- int main()
- {
- memset(nxt,0,sizeof(nxt));
- memset(fir,0,sizeof(fir));
- n=read();m=read();
- cnt=1;
- for(int i=1;i<=m;i++)
- {
- edge[i].a=read();edge[i].b=read();edge[i].c=read();
- }
- s=read();t=read();l=read();
- for(int i=1;i<=m;i++)
- {
- if(edge[i].c<l)
- {
- x=edge[i].a;
- y=edge[i].b;
- e[++cnt].u=x;e[cnt].v=y;e[cnt].cap=1;e[cnt].flow=0;
- nxt[cnt]=fir[x];fir[x]=cnt;
- e[++cnt].u=y;e[cnt].v=x;e[cnt].cap=1;e[cnt].flow=0;
- nxt[cnt]=fir[y];fir[y]=cnt;
- }
- }
- bfs();
- ansx+=isap();
- cnt=1;
- memset(nxt,0,sizeof(nxt));
- memset(fir,0,sizeof(fir));
- memset(e,0,sizeof(e));
- for(int i=1;i<=m;i++)
- {
- if(edge[i].c>l)
- {
- x=edge[i].a;
- y=edge[i].b;
- e[++cnt].u=x;e[cnt].v=y;e[cnt].cap=1;e[cnt].flow=0;
- nxt[cnt]=fir[x];fir[x]=cnt;
- e[++cnt].u=y;e[cnt].v=x;e[cnt].cap=1;e[cnt].flow=0;
- nxt[cnt]=fir[y];fir[y]=cnt;
- }
- }
- bfs();
- ansx+=isap();
- printf("%d\n",ansx);
- return 0;
- }
BZOJ-2561-最小生成树 题解(最小割)的更多相关文章
- BZOJ 2561 最小生成树 | 网络流 最小割
链接 BZOJ 2561 题解 用Kruskal算法的思路来考虑,边(u, v, L)可能出现在最小生成树上,就是说对于所有边权小于L的边,u和v不能连通,即求最小割: 对于最大生成树的情况也一样.容 ...
- bzoj 2561: 最小生成树【最小割】
看错题了以为多组询问吓得不行-- 其实还挺好想的,就是数据范围一点都不网络流.把U作为s,V作为t,以最小生成树为例,(U,V,L)要在最小生成树上,就要求所有边权比L小的边不能连通(U,V)所在的联 ...
- BZOJ 2561: 最小生成树【最小割/最大流】
Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v), ...
- BZOJ_2561_最小生成树_最小割
BZOJ_2561_最小生成树_最小割 题意: 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条 ...
- BZOJ 2561: 最小生成树(最小割)
U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...
- bzoj千题计划322:bzoj2561: 最小生成树(最小割)
https://www.lydsy.com/JudgeOnline/problem.php?id=2561 考虑Kruscal算法求最小生成树的流程 如果 u和v之间的长为L的边能出现在最小生成树里, ...
- BZOJ 2521: [Shoi2010]最小生成树(最小割)
题意 对于某一条无向图中的指定边 \((a, b)\) , 求出至少需要多少次操作.可以保证 \((a, b)\) 边在这个无向图的最小生成树中. 一次操作指: 先选择一条图中的边 \((u, v)\ ...
- 【bzoj2521】[Shoi2010]最小生成树 网络流最小割
题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...
- 【bzoj2561】最小生成树 网络流最小割
题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...
- BZOJ2561 最小生成树 【最小割】
题目 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多 ...
随机推荐
- Struts2入门(二)——配置拦截器
一.前言 之前便了解过,Struts 2的核心控制器是一个Filter过滤器,负责拦截所有的用户请求,当用户请求发送过来时,会去检测struts.xml是否存在这个action,如果存在,服务器便会自 ...
- JavaScript 9种类型
Undefined . Null . Boolean . String . Number . Object . Reference .List .Completion
- 《Web开发过滤Javascript、HTML的方法》
JavaScript过滤方法: 第一种方案:使用 htmlspecialchars 函数转换特殊字符和使用 nl2br 函数插入一些必要的 <br /> 标签. $comment = &l ...
- json简单使用
web工程中如何将大量数据从服务器端传送到浏览器一直是很重要的一个问题. 其中一个解决方法是在服务器端将将数据封装成json格式,然后传给前台.废话不多说,下面讲干货. 1.要用json必须下载一个库 ...
- 块级标签包含行内标签底部出现3px间隔的解决办法
当块级标签(如div)内包含了行内标签(如img),则外层元素与内层元素底部会出现3px的间隔: 代码如下: <!doctype html> <html lang="en& ...
- JQuery plugin ---- simplePagination.js API
CSS Themes "light-theme" "dark-theme" "compact-theme" How To Use Step ...
- ASP.NET MVC 5 05 - 视图
PS: 唉,这篇随笔国庆(2015年)放假前几天开始的,放完假回来正好又赶上年底,公司各种破事儿. 这尼玛都写跨年了都,真服了.(=_=#) 好几次不想写了都. 可是又不想浪费这么多,狠不下心删除.没 ...
- backup log is terminating abnormally because for write on file failed: 112(error not found)
昨天遇到一个案例,YourSQLDba做事务日志备份时失败,检查YourSQLDba输出的错误信息如下: <Exec> <ctx>yMaint.backups</ctx& ...
- TCP三次握手/四次挥手详解
一. TCP/IP协议族 TCP/IP是一个协议族,通常分不同层次进行开发,每个层次负责不同的通信功能.包含以下四个层次: 1. 链路层,也称作数据链路层或者网络接口层,通常包括操作系统中的设备驱动程 ...
- MVC中的BASE.ONACTIONEXECUTING(FILTERCONTEXT) 的作用
一句话,就是调用base.OnActionExecuting(filterContext)这个后,才会执行后续的ActionFilter,如果你确定只有一个,或是不想执行后续的话,那么可以不用调用该语 ...