【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, ...
随机推荐
- Frequently Asked Questions - P-thresholds
Source: http://mindhive.mit.edu/book/export/html 1. What is the multiple-comparison problem? What is ...
- [转]Gson过滤字段
原文地址:http://my.oschina.net/orgsky/blog/368768 摘要 Gson过滤字段 Gson过滤字段 Gson 过滤 字段 属性 目录[-] 最简单的用法 方法1:排除 ...
- Android开篇(转)
转自:http://gityuan.com/android/ 一.简述 Android系统非常庞大.错中复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统 ...
- flex布局模式简单概述
CSS3中新增一种弹性布局模型:flexbox.网上关于flex的介绍很多,这里介绍下常用的几个属性.弹性布局的特点是非常灵活.可根据剩余的宽高,灵活布局. 先用图片说明flex具有哪些属性.(网上盗 ...
- 基于VirtualBox安装Ubuntu图文教程
基于VirtualBox虚拟机安装Ubuntu图文教程 一. 下载安装VirtualBox 官网下载VirtualBox,目前版本:VirtualBox 5.1.8 for Windows hosts ...
- 如何在 apache 中开启 gzip 压缩服务
服务器设置 gzip 压缩是 web 开发里很普遍的做法.假设你要请求一个 100k 的文件,网络传输速度为 50k/s,需要 2s 才能得到数据,但是如果在服务器设置了 gzip 压缩,将服务端的文 ...
- stack overflow错误分析
stack overflow(堆栈溢出)就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据. 或者解释为 在长字符串中嵌入一段代码,并将过程的返回地址 ...
- WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互
方法一 使用微软官方组件Interop.MSScriptControl 1.msscript.ocx下载的地址 http://www.microsoft.com/downloads/details ...
- android中的图片处理
大图片处理 大图片处理是将原来像素高的转换为像素低的图片,比如原来图片是1024*768的,而手机屏幕是800*600的,这时候就需要进行转换.转换的方式很简单就是等比例缩放. package xid ...
- Android之Activity启动模式
正常模式 每个应用都有一个任务栈,任务栈中保存着已创建的Activity,先创建的Activity先入栈,栈顶是当前正在显示的activity(running),这是正常模式下的Activity的管理 ...