【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)
2502: 清理雪道
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 594 Solved: 318
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 3
1 7
2 4 5
1 8
1 8
0
2 6 5
0
Sample Output
HINT
Source
Solution
有下界的最小流
又题很容易看出,每条边的流至少为1,即下界唯一,总流最小,很显然 下界为1的最小流 无上界或者说上界为inf
不能直接求解,考虑如下:
给每条边加一条下界容量1,一条上界容量inf;
S到各点连边,下界0,上界inf;各点到T连边,下界0,上界inf;
求出最小流就是答案,所以考虑最小流的求法:
添加超级源汇变成 无源汇可行流 ,这就需要连T-->S容量为inf, 这样可以得到满足下界的流量FlowSum,但显然不是所求
去掉原来的S,T,再进行一遍得到Flow,最后的答案,即最小流为FlowSum-Flow
自己是这样理解的:
再求可行流的时候,所得的流量并非全在 (T,S)这条直连路径 上,而同样可能在T-S之间的路径上,所以显然不是最小
那么再做一遍,可以理解为 退流 ,退掉尽可能多的流,由于下界是不会被退掉的,所以差值就是所求最小流
Code
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<queue>
- #include<vector>
- using namespace std;
- 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;
- }
- #define maxn 500
- #define maxm 1000010
- int n,m,ind[maxn],S,SS,T,TT;
- struct EdgeNode{int to,next,cap;}edge[maxm];
- int head[maxn],cnt=;
- void add(int u,int v,int w)
- {
- cnt++;
- edge[cnt].to=v;edge[cnt].cap=w;edge[cnt].next=head[u]; head[u]=cnt;
- }
- void insert(int u,int v,int w) {add(u,v,w); add(v,u,);}
- int dis[maxn],que[maxn<<],cur[maxn];
- bool bfs()
- {
- for (int i=; i<=T; i++) dis[i]=-;
- que[]=S; dis[S]=; int he=,ta=;
- while (he<ta)
- {
- int now=que[he++];
- for (int i=head[now]; i; i=edge[i].next)
- if (edge[i].cap && dis[edge[i].to]==-)
- dis[edge[i].to]=dis[now]+,que[ta++]=edge[i].to;
- }
- return dis[T]!=-;
- }
- int dfs(int loc,int low)
- {
- if (loc==T) return low;
- int w,used=;
- for (int i=cur[loc]; i; i=edge[i].next)
- if (edge[i].cap && dis[edge[i].to]==dis[loc]+)
- {
- w=dfs(edge[i].to,min(low-used,edge[i].cap));
- edge[i].cap-=w; edge[i^].cap+=w;
- used+=w; if (edge[i].cap) cur[loc]=i;
- if (used==low) return low;
- }
- if (!used) dis[loc]=-;
- return used;
- }
- #define inf 0x7fffffff
- int dinic()
- {
- int tmp=;
- while (bfs())
- {
- for (int i=; i<=T; i++) cur[i]=head[i];
- tmp+=dfs(S,inf);
- }
- return tmp;
- }
- int a[maxn][maxn];
- int Work()
- {
- for (int i=; i<=n; i++)
- for (int j=; j<=a[i][]; j++)
- insert(i,a[i][j],inf),ind[i]--,ind[a[i][j]]++;
- SS=n+; TT=SS+; S=TT+;T=S+;
- for(int i=; i<=n; i++)
- {
- insert(SS,i,inf);
- insert(i,TT,inf);
- if(ind[i]>) insert(S,i,ind[i]);
- else insert(i,T,-ind[i]);
- }
- insert(TT,SS,inf);
- int Flow=,FlowSum=;
- Flow=dinic();
- FlowSum=edge[cnt].cap;
- head[SS]=edge[head[SS]].next;
- head[TT]=edge[head[TT]].next;
- for (int i=head[S]; i; i=edge[i].next)
- edge[i].cap=,edge[i^].cap=;
- for (int i=head[T]; i; i=edge[i].next)
- edge[i].cap=,edge[i^].cap=;
- insert(S,TT,inf); insert(SS,T,inf);
- Flow=dinic();
- return FlowSum-Flow;
- }
- int main()
- {
- n=read();
- for (int t,i=; i<=n; i++)
- {
- a[i][]=read();
- for (int j=; j<=a[i][]; j++)
- a[i][j]=read();
- }
- printf("%d\n",Work());
- return ;
- }
【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)的更多相关文章
- Bzoj 2502: 清理雪道 有上下界网络流_最小流
好长时间没有写网络流了,感觉好手生.对于本题,设一个源点 $s$ 和 $t$.1.由 $s$ 向每个点连一条没有下界,容量为无限大的边,表示以该点为起点.2.由每个点向 $t$ 连一条没有下界,容量为 ...
- BZOJ 2502: 清理雪道 | 有上下界最小流
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #defi ...
- BZOJ 2502: 清理雪道
BZOJ 2502: 清理雪道 标签(空格分隔): OI-BZOJ OI-最小流 OI-上下界网络流 Time Limit: 10 Sec Memory Limit: 128 MB Descripti ...
- bzoj 2502 清理雪道 (有源汇上下界最小流)
2502: 清理雪道 Time Limit: 10 Sec Memory Limit: 128 MB Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场 ...
- BZOJ 2502: 清理雪道 [最小流]
2502: 清理雪道 题意:任意点出发任意次每条边至少经过一次最小花费. 下界1,裸最小流.... #include <iostream> #include <cstdio> ...
- BZOJ 2502 清理雪道(有源汇上下界最小流)
题面 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机, ...
- bzoj 2502 清理雪道(有源汇的上下界最小流)
[题意] 有一个DAG,要求每条边必须经过一次,求最少经过次数. [思路] 有上下界的最小流. 边的下界为1,上界为无穷.构造可行流模型,先不加ts边跑一遍最大流,然后加上t->s的inf边跑 ...
- BZOJ 2502 清理雪道/ Luogu P4843 清理雪道 (有源汇上下界最小流)
题意 有一个有向无环图,求最少的路径条数覆盖所有的边 分析 有源汇上下界最小流板题,直接放代码了,不会的看dalao博客:liu_runda 有点长,讲的很好,静心看一定能看懂 CODE #inclu ...
- bzoj 2502: 清理雪道【有上下界有源汇最小流】
对于原有边,流区间是(1,inf),按着原边连,然后再连(s,i,(0,inf)),(i,t,(0,inf))表示任意位置进出雪场 按着这个建出新图 然后最小流的方法是先跑可行流,设ans为(t,s, ...
随机推荐
- swift 集合类型(一)
基本的数组结构Array: var shoppingList: String[] = ["Eggs", "Milk"] 这个shoppingList和传统意义上 ...
- 注册URL模式与HttpHandler的映射关系
注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...
- 通过ssh tunnel连接内网ECS和RDS
通过ssh tunnel连接内网ECS和RDS 这里讲了ssh tunnel的原理.很清晰. 此后又给外网访问内网增加了一种思路.感觉特别棒. 拓宽了思路:
- QT 对话框二
QMessageBox类 information()函数,主要是提示功能,不需要用户选择 StandardButton QMessageBox::information ( QWidget *pare ...
- hadoop:将WordCount打包成独立运行的jar包
hadoop示例中的WordCount程序,很多教程上都是推荐以下二种运行方式: 1.将生成的jar包,复制到hadoop集群中的节点,然后运行 $HADOOP_HOME/bin/hadoop xxx ...
- React Native中设计主题机制
昨天和同事讨论组件隔离性的时候讨论到关于默认样式的问题:很多情况下我们希望能够把组件设计为通用的,然后在具体项目中给他们指定一些通用的样式,譬如:背景颜色.默认字体等等.这听起来在CSS下运作起来就很 ...
- Javascript中判断数组的正确姿势
在 Javascript 中,如何判断一个变量是否是数组? 最好的方式是用 ES5 提供的 Array.isArray() 方法(毕竟原生的才是最屌的): var a = [0, 1, 2]; con ...
- JQuery功能查询页
JQuery在前端开发中已经是常用的不能再常用的库了.最近的项目中使用到了JQuery,我第一次接触它的时候为了学习,把常用的操作指令用比较小的字体写在一页word上,打印出来贴在桌子上,用来让自己时 ...
- Sql 2012 远程数据库连接
新装好的数据库,各种远程连接设置都设置好后.发现还是连接不上. 这时候,问题可能出在端口上,远程连接的时候需要指明端口.动态端口一般都会变.在本机连接时候,会自动选择端口.在远程访问时候,就必须要指明 ...
- xml序列化及反序列化.net对象
序列化一个类通常添加[XmlRoot("根节点名字")] 找到要序列化的内容 对要序列化的类添加 [Serializable]属性用于序列化 对于要序列化的字段添加 [XmlEl ...