BZOJ 1930 吃豆豆(费用流)
首先这题的两条线不相交的限制可以去掉,因为如果相交的话把点换一换是不影响最终结果的。
剩下的费用流建图是显然的,把点拆为两个,建立超级源点s和源点ss汇点t,连边(s,ss,2,0). 对于每个点,连边(ss,i,1,0), (i,i',1,1),(i',t,1,0).
这样跑一遍费用流就行了,然而此题的边数可以达到n^2.无疑是OLE的。需要优化。
容易发现,对于点(i,j),(j,k),(i,k).如果这些点都可以互相到达的话,那么(i,k)这条边是不必要的。因为通过j到达k是不会比结果劣的。
所以启发我们将点按x坐标以第一关键字排序,y第二关键字排序。对于相同的列,选择大于前一列的y坐标且最小的点连边。
这样建边之后还存在一个问题,可能有个点两个吃豆人都需要经过,于是再建边(i,i',1,0),(i',j,2,0).
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Node{int x, y;}node[];
struct Edge{int to, next, cap, flow, cost;}edge[];
int head[N], tol, pre[N], dis[N], nn;
bool vis[N];
queue<int>q; void init(int n){nn=n; tol=; mem(head,-);}
void addedge(int u, int v, int cap, int cost){
edge[tol].to=v; edge[tol].cap=cap; edge[tol].cost=cost; edge[tol].flow=; edge[tol].next=head[u]; head[u]=tol++;
edge[tol].to=u; edge[tol].cap=; edge[tol].cost=-cost; edge[tol].flow=; edge[tol].next=head[v]; head[v]=tol++;
}
bool spfa(int s, int t){
FO(i,,nn) dis[i]=INF, vis[i]=false, pre[i]=-;
dis[s]=; vis[s]=true; q.push(s);
while (!q.empty()) {
int u=q.front(); q.pop(); vis[u]=false;
for (int i=head[u]; i!=-; i=edge[i].next) {
int v=edge[i].to;
if (edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost) {
dis[v]=dis[u]+edge[i].cost; pre[v]=i;
if (!vis[v]) vis[v]=true, q.push(v);
}
}
}
if (pre[t]==-) return false;
else return true;
}
int minCostMaxflow(int s, int t, int &cost){
int flow=; cost=;
while (spfa(s,t)) {
int Min=INF;
for (int i=pre[t]; i!=-; i=pre[edge[i^].to]) {
if (Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow;
}
for (int i=pre[t]; i!=-; i=pre[edge[i^].to]) {
edge[i].flow+=Min; edge[i^].flow-=Min; cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
bool comp(Node a, Node b){
if (a.x==b.x) return a.y<b.y;
else return a.x<b.x;
}
int main ()
{
int n, s, ss, t;
scanf("%d",&n);
s=; ss=*n+; t=*n+;
init(t+);
addedge(s,ss,,);
FOR(i,,n) {
scanf("%d%d",&node[i].x,&node[i].y);
addedge(ss,i,,); addedge(i,n+i,,-); addedge(i,n+i,,); addedge(n+i,t,,);
}
sort(node+,node+n+,comp);
FOR(i,,n) {
int mi=INF, now=;
FOR(j,i+,n) {
if (now==node[j].x||node[j].y<node[i].y) continue;
if (node[j].y<mi) mi=node[j].y, now=node[j].x, addedge(n+i,j,,);
}
}
int ans;
minCostMaxflow(s,t,ans);
printf("%d\n",-ans);
return ;
}
BZOJ 1930 吃豆豆(费用流)的更多相关文章
- bzoj 1930: [Shoi2003]pacman 吃豆豆 [费用流]
1930: [Shoi2003]pacman 吃豆豆 题意:两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的 ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- BZOJ 3171 循环格(费用流)
题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...
- BZOJ 1070 修车 【费用流】
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序, ...
- BZOJ 1927 星际竞速(费用流)
考虑费用流,题目要求走n个点都走完且恰好一次,显然流量的限制为n. 建立源点s和汇点t,并把每个星球拆成两个点i和i',分别表示已到达该点和经过该点. 对于能力爆发,建边(s,i',1,w). 对应高 ...
- BZOJ 1221 软件开发(费用流)
容易看出这是显然的费用流模型. 把每天需要的餐巾数作为限制.需要将天数拆点,x’表示每天需要的餐巾,x’’表示每天用完的餐巾.所以加边 (s,x',INF,0),(x'',t,INF,0). 餐巾可以 ...
- bzoj 1520 [POI2006]Szk-Schools 费用流
[POI2006]Szk-Schools Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 743 Solved: 381[Submit][Status][ ...
随机推荐
- MySQL高级第四章——MySQL的锁机制
一.概述 1.定义 锁是计算机协调多个进程或线程并发访问某一资源的限制. 2.分类 操作类型来分: 读锁(共享锁)和写锁(排它锁) 数据粒度来分: 表锁和行锁 二.三锁 1.表锁——偏读 特点: 偏向 ...
- MVC保存二进制到数据库,并显示文件的方法(图片显示)
通过两篇文章解决了数据库存储图片并显示到View的方法: http://blog.sina.com.cn/s/blog_6da396a50101639u.htmlhttp://www.cnblogs. ...
- 长沙Uber优步司机奖励政策(1月4日~1月10日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- nexys4开发板使用-第一篇(未完成)
1. 下去下个原理图.今天准备研究下DDR的控制,看介绍新一代的Nexys 4 DDR最值得被关注的改良是将原先的16 MiBCellularRAM升级为128 MiB的DDR2 SDRAM内存.Di ...
- linux常用的命令之一chmod
用权限 : 所有使用者 使用方式 : chmod [-cfvR] [--help] [--version] mode file... u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(g ...
- ntp-redhat 同步时间配置
1. 选作一个机器作为ntp 服务端,例如 ip 为192.168.0.1 1)安装 ntp服务 yum install ntp 2) 修改ntp.conf 文件 vi /etc/ntp.conf 注 ...
- Linux命令应用大词典-第40章 网络客户端
40.1 elinks:字符模式的Web浏览器 40.2 wget:从Web网站下载文件 40.3 curl:传输URL 40.4 lynx:通用分布式信息的万维网浏览器 40.5 lftp:实现文件 ...
- 孤荷凌寒自学python第八十天开始写Python的第一个爬虫10
孤荷凌寒自学python第八十天开始写Python的第一个爬虫10 (完整学习过程屏幕记录视频地址在文末) 原计划今天应当可以解决读取所有页的目录并转而取出所有新闻的功能,不过由于学习时间不够,只是进 ...
- Ubuntu—查看进程并关闭进程
环境:Ubuntu终端 命令:ps -aux 功能:查看进程信息 命令:kill 进程号(PID) 功能:杀死进程
- 网络安全部门的漏洞扫描让你头痛不已么——PHP环境选它就可以了
最近网络安全要求是越来越严,原来PHP编写的程序在XAMPP或者其他环境下总会被某款软件扫出漏洞,进而上级部门就停止了我们服务器的外网出口,然而自从发现了一款安全环境神器UPUPW后,这样的问题就再也 ...