【BZOJ 1930】 [Shoi2003]pacman 吃豆豆 最大费用最大流
如果你知道他是网络流的话你就很快会想到一个最大费用最大流的模型,然后你发现可能T,然而你发现你只用增广两次,然后你就开心的打了出来,然后发现被稠密图里spfa的丧病时间复杂度坑了,还是会T。于是我就开始找优化方式,一开始我想优化边数,可是发现,不会,然后我就开始瞎搞。我把第一遍spfa改成了最长上升子序列,第二遍是在第一遍的基础上建的图,由于没有反向边所以快了许多,然后就过了,高兴。我去看了看题解里面说的是优化边数,它的思路就是把一个边拆开,就是说,我们原来连边都是从前往后从低向高连(如果按照x排序的话),那么我们把两个点之间的边拆成最小,就是说,连边的两点之间不会有高度在其之间的点,虽然说这样连边仍然有可能把边数卡到百万级别但是会好很多,就是要注意这样做的话必须要让拆开的点之间连Inf流量以支持交通运输,所以我就把这两个东西结合了一下。
这道题的启发在于对于一些并不像网络流的东西进行网络流,以及通过观察特点来更加准确的估算时间复杂度以不至于做出错误判断,还有就是替换算法来提高时间效率,最重要的一点当然就是优化边数的方法,就是把各个边等效化同时增加一些边的功能以减少边数,换言之就是把边拆分,更准确的说就是找到基底。
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=;
const int Inf=0x3f3f3f3f;
const int oo=0xafafafaf;
struct V{
int to,next,c;
}c[N*N/];
int head[N*],t;
inline void add(int x,int y,int z){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].c=z;
}
int dis[N*];
int cnt[N],anc[N];
int q[N*],front,back;
bool in[N*];
bool via[*N][*N];
int n;
int S,T,tail;
struct Point{
int x,y;
}poi[N];
inline bool comp(Point a,Point b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline void spfa(){
memset(dis,0xaf,sizeof(dis));
q[back++]=S,dis[S]=,in[S]=true;
if(back==(N<<))back=;
while(front!=back){
int x=q[front++];in[x]=false;
if(front==(N<<))front=;
for(int i=head[x];i;i=c[i].next)
if(dis[x]+c[i].c>dis[c[i].to]){
dis[c[i].to]=dis[x]+c[i].c;
if(!in[c[i].to]){
q[back++]=c[i].to,in[c[i].to]=true;
if(back==(N<<))back=;
}
}
}
}
int main(){
scanf("%d",&n);
if(n==){
printf("");
return ;
}
if(n==){
printf("");
return ;
}
int ans=;
S=n+n+,T=n+n+;
for(int i=;i<=n;++i)
scanf("%d%d",&poi[i].x,&poi[i].y);
std::sort(poi+,poi+n+,comp);
for(int i=;i<=n;++i){
cnt[i]=,anc[i]=;
for(int j=i-;j>;--j)
if(poi[j].y<=poi[i].y&&cnt[i]<cnt[j]+)
cnt[i]=cnt[j]+,anc[i]=j;
if(cnt[i]>ans)
ans=cnt[i],tail=i;
}
int last=T;
for(int i=tail;i;i=anc[i]){
via[i][i+n]=true;
via[i+n][last]=true;
add(last,i+n,);
add(i+n,i,-);
last=i;
}
via[S][last]=true;
add(last,S,);
for(int i=;i<=n;++i){
add(S,i,);
add(i+n,T,);
if(via[i][i+n]==false)add(i,i+n,);
add(i,i+n,);
for(int j=i+,min=Inf;j<=n;++j)
if(poi[j].y>=poi[i].y&&poi[j].y<min)
add(i+n,j,),min=poi[j].y;
}
spfa(),ans+=dis[T];
printf("%d",ans);
return ;
}
结合的优秀代码
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=;
const int Inf=0x3f3f3f3f;
const int oo=0xafafafaf;
struct V{
int to,next,f,c;
}c[N*N];
int head[N*],t=;
inline void add(int x,int y,int z,int _){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].f=z,c[t].c=_;
}
int dis[N*],anc[N*];
int q[N*],front,back;
bool in[N*];
int n;
int S,T,source;
struct Point{
int x,y;
}poi[N];
inline bool look(Point a,Point b){
return b.x>=a.x&&b.y>=a.y;
}
inline bool comp(Point a,Point b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool spfa(){
memset(dis,0xaf,sizeof(dis));
q[back++]=S,dis[S]=,in[S]=true;
if(back==(N<<))back=;
while(front!=back){
int x=q[front++];in[x]=false;
if(front==(N<<))front=;
for(int i=head[x];i;i=c[i].next)
if(c[i].f&&dis[x]+c[i].c>dis[c[i].to]){
dis[c[i].to]=dis[x]+c[i].c,anc[c[i].to]=i;
if(!in[c[i].to]){
q[back++]=c[i].to,in[c[i].to]=true;
if(back==(N<<))back=;
}
}
}
return dis[T]!=oo;
}
inline int shoot(){
int f=Inf;
for(int i=anc[T];i;i=anc[c[i^].to])f=std::min(f,c[i].f);
for(int i=anc[T];i;i=anc[c[i^].to])c[i].f-=f,c[i^].f+=f;
return f*dis[T];
}
int main(){
scanf("%d",&n);
source=n+n+,S=n+n+,T=n+n+;
add(S,source,,),add(source,S,,);
for(int i=;i<=n;++i)
scanf("%d%d",&poi[i].x,&poi[i].y);
std::sort(poi+,poi+n+,comp);
for(int i=;i<=n;++i){
add(source,i,Inf,),add(i,source,,);
add(i+n,T,Inf,),add(T,i+n,,);
add(i,i+n,,),add(i+n,i,,-);
add(i,i+n,Inf,),add(i+n,i,,);
for(int j=i+,min=Inf;j<=n;++j)
if(poi[j].y>=poi[i].y&&poi[j].y<min)
add(i+n,j,Inf,),add(j,i+n,,),min=poi[j].y;
}
int ans=;
while(spfa())ans+=shoot();
printf("%d",ans);
return ;
}
质朴的边优化费用流
【BZOJ 1930】 [Shoi2003]pacman 吃豆豆 最大费用最大流的更多相关文章
- bzoj 1930: [Shoi2003]pacman 吃豆豆 [费用流]
1930: [Shoi2003]pacman 吃豆豆 题意:两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的 ...
- 【BZOJ1930】[Shoi2003]pacman 吃豆豆 最大费用最大流
[BZOJ1930][Shoi2003]pacman 吃豆豆 Description 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会 ...
- 1930: [Shoi2003]pacman 吃豆豆
1930: [Shoi2003]pacman 吃豆豆 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1969 Solved: 461[Submit][ ...
- BZOJ1930 [Shoi2003]pacman 吃豆豆
dp,首先建出图,f[i][j]表示a吃到了i点,b吃到了j点的最大值,转移的时候转移拓扑序小的那一维,如果i拓扑序小于j,那么转移到f[k][j],否则转移到f[i][k],建出的图边数也要优化, ...
- [bzoj]1930 pacman吃豆豆
Description 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他 ...
- 【BZOJ1930】【SHOI2003】吃豆豆
初见杀…… 原题: 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行 ...
- BZOJ 3876 [AHOI/JSOI2014]支线剧情 (最小费用可行流)
题面:洛谷传送门 BZOJ传送门 题目大意:给你一张有向无环图,边有边权,让我们用任意条从1号点开始的路径覆盖这张图,需要保证覆盖完成后图内所有边都被覆盖至少一次,求覆盖路径总长度的最小值 最小费用可 ...
- bzoj 1877 [SDOI2009]晨跑(最小费用最大流)
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...
- bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)
1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1576 Solved: 954[Submit][Statu ...
随机推荐
- Vue 服务器端渲染(一)
什么是服务器端渲染(SSR)? Vue.js 是构建客户端应用程序的框架.默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM.然而,也可以将同一个组件渲染为服务器端的 HT ...
- 什么是高防服务器?如何搭建DDOS流量攻击防护系统
关于高防服务器的使用以及需求,从以往的联众棋牌到目前发展迅猛的手机APP棋牌,越来越多的游戏行业都在使用高防服务器系统,从2018年1月到11月,国内棋牌运营公司发展到了几百家. 棋牌的玩法模式从之前 ...
- 【PHP】进一法取整、四舍五入取整、忽略小数等的取整数方法大全
PHP取整数函数常用的四种方法,下面收集了四个函数:经常用到取整的函数,今天小小的总结一下!其实很简单,就是几个函数而已--主要是:ceil,floor,round,intval PHP取整数函数常用 ...
- SharePoint显示错误信息
在SharePoint项目中,一般如果发生错误,SharePoint会弹出它自定义的报错页面,一般就显示"Something went wrong",如果光是看这一句话, ...
- jmeter使用beanshell构造参数化
1.先在本地写一个java类,用来随机生成一个数字,如: package com.jmeter.test; public class BeanShellTest { public int getRan ...
- 孤荷凌寒自学python第七十一天开始写Python的第一个爬虫
孤荷凌寒自学python第七十一天开始写Python的第一个爬虫 (完整学习过程屏幕记录视频地址在文末) 在了解了requests模块和BeautifulSoup模块后,今天开始真正写一个自己的爬虫代 ...
- SPOJ 694
题面 题意: 给一个字符串,求它有多少个不同的子串 多组数据. Solution : 模板题,用所有的减去重复的即可. #include <cstdio> #include <alg ...
- C++ 学习笔记之——输入和输出
在 C++ 中,我们通过调用输入输出流库中的流对象 cin 和 cout 来实现输入和输出. #include <iostream> using namespace std; int ma ...
- DFS实现模板
以如下图的无向图G4为例,进行图的深度优先搜索: 假设从顶点v1出发进行搜索,在访问了顶点v1之后,选择邻接点v2.因为v2未曾访问,则从v2出发进行搜索.依次类推,接着从v4 .v8 .v5出发进行 ...
- Week2 Teamework from Z.XML - 必应缤纷桌面助手 - 软件分析与用户需求调查
软件分析与用户需求调查(2013) from Z.XML 本次团队作业要求: 通过定性, 定量地分析, 总结和评定某软件是否满足了目标用户的需求,并把分析的过程和结果用博客表达出来. 选题:必应缤纷桌 ...