BZOJ4200 洛谷2304 UOJ132:[NOI2015]小园丁与老司机——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4200
https://www.luogu.org/problemnew/show/P2304
http://uoj.ac/problem/132
小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面。田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2,3,…,n,每棵树可以看作平面上的一个点,其中第 ii 棵树 (1≤i≤n1≤i≤n) 位于坐标 (xi,yi)(xi,yi)。任意两棵树的坐标均不相同。老司机 Mr. P 从原点 (0,0)(0,0) 驾车出发,进行若干轮行动。每一轮,Mr. P 首先选择任意一个满足以下条件的方向:为左、右、上、左上 45∘45∘ 、右上 45∘45∘ 五个方向之一。沿此方向前进可以到达一棵他尚未许愿过的树。完成选择后,Mr. P 沿该方向直线前进,必须到达该方向上距离最近的尚未许愿的树,在树下许愿并继续下一轮行动。如果没有满足条件的方向可供选择,则停止行动。他会采取最优策略,在尽可能多的树下许愿。若最优策略不唯一,可以选择任意一种。不幸的是,小园丁 Mr. S 发现由于田野土质松软,老司机 Mr. P 的小汽车在每轮行进过程中,都会在田野上留下一条车辙印,一条车辙印可看作以两棵树(或原点和一棵树)为端点的一条线段。在 Mr. P 之后,还有很多许愿者计划驾车来田野许愿,这些许愿者都会像 Mr. P 一样任选一种最优策略行动。Mr. S 认为非左右方向(即上、左上 45∘45∘ 、右上 45∘45∘ 三个方向)的车辙印很不美观,为了维护田野的形象,他打算租用一些轧路机,在这群许愿者到来之前夯实所有“可能留下非左右方向车辙印”的地面。“可能留下非左右方向车辙印”的地面应当是田野上的若干条线段,其中每条线段都包含在某一种最优策略的行进路线中。每台轧路机都采取满足以下三个条件的工作模式:从原点或任意一棵树出发。只能向上、左上 45∘45∘ 、右上 45∘45∘ 三个方向之一移动,并且只能在树下改变方向或停止。只能经过“可能留下非左右方向车辙印”的地面,但是同一块地面可以被多台轧路机经过。现在 Mr. P 和 Mr. S 分别向你提出了一个问题:请给 Mr .P 指出任意一条最优路线。请告诉 Mr. S 最少需要租用多少台轧路机。
哈哈哈我可能是疯了所以才去做了码农题,然后dp不会最小流写跪哈哈哈
直接看这个吧,心累到懒得讲题解了:https://blog.csdn.net/litble/article/details/80463466
另外开O2的时候普通的最小流也可以通过,不开的时候就会奇妙RE。
(自认码风不错)
#include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int INF=1e9; const int N=5e4+5; inline int read(){int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } struct point{int x,y,b1,b2,id; }p[N]; int n,b[N],c[N],d[N],e[N],l1,l2,l3,l4; int to[3][N],lft[N],straight[N],rigt[N]; int f[N],g[N],flor[N],num[N]; vector<int>ty[N]; inline bool cmpx(point a,point b){return a.x<b.x; } inline bool cmpy(point a,point b){return a.y>b.y; } void LSH(){sort(b+1,b+l1+1);sort(c+1,c+l2+1);sort(d+1,d+l3+1);sort(e+1,e+l4+1);l1=unique(b+1,b+l1+1)-b-1,l2=unique(c+1,c+l2+1)-c-1;l3=unique(d+1,d+l3+1)-d-1,l4=unique(e+1,e+l4+1)-e-1;for(int i=1;i<=n;i++){p[i].x=lower_bound(b+1,b+l1+1,p[i].x)-b;p[i].y=lower_bound(c+1,c+l2+1,p[i].y)-c;p[i].b1=lower_bound(d+1,d+l3+1,p[i].b1)-d;p[i].b2=lower_bound(e+1,e+l4+1,p[i].b2)-e;} } void init(){LSH();sort(p+1,p+n+1,cmpy);for(int i=1;i<=n;i++){int id=p[i].id;to[0][id]=lft[p[i].b2];to[1][id]=straight[p[i].x];to[2][id]=rigt[p[i].b1];lft[p[i].b2]=id;straight[p[i].x]=id;rigt[p[i].b1]=id;}sort(p+1,p+n+1,cmpx);for(int i=1;i<=n;i++){ty[p[i].y].push_back(p[i].id);flor[p[i].id]=p[i].y;num[p[i].id]=ty[p[i].y].size()-1;} } int pre[N],lrs[N]; void output(int id){if(id!=lrs[id]){int fll=flor[id];if(num[id]<num[lrs[id]]){for(int i=num[id]-1;i>=0;i--)printf("%d ",ty[fll][i]);for(int i=num[id]+1;i<=num[lrs[id]];i++)printf("%d ",ty[fll][i]);}else{int sz=ty[fll].size();for(int i=num[id]+1;i<sz;i++)printf("%d ",ty[fll][i]);for(int i=num[id]-1;i>=num[lrs[id]];i--)printf("%d ",ty[fll][i]);}}id=lrs[id];if(pre[id]){printf("%d ",pre[id]);output(pre[id]);} } void work1(){init();for(int i=l2;i>=1;i--){int maxn=0,id=0,sz=ty[i].size();for(int j=0;j<sz;j++){//处理直行和向右再左走int I=ty[i][j];int J1=to[0][I],J2=to[1][I],J3=to[2][I];if(J1&&g[I]<f[J1])g[I]=f[J1],pre[I]=J1;if(J2&&g[I]<f[J2])g[I]=f[J2],pre[I]=J2;if(J3&&g[I]<f[J3])g[I]=f[J3],pre[I]=J3;if(maxn>g[I]+1)f[I]=maxn,lrs[I]=id;else f[I]=g[I]+1,lrs[I]=I;if(sz-j+g[I]>maxn)maxn=sz-j+g[I],id=I;}maxn=id=0;for(int j=sz-1;j>=0;j--){//处理向左再右走int I=ty[i][j];if(maxn>f[I])f[I]=maxn,lrs[I]=id;if(g[I]+j+1>maxn)maxn=g[I]+j+1,id=I;}}printf("%d\n",f[n]-1);output(n);puts(""); } struct node{int to,nxt,w; }edge[N*10]; int cnt,head[N],S,T,du[N]; int cur[N],lev[N],dui[N]; bool ok[N]; inline void adde(int u,int v,int w){edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;edge[++cnt].to=u;edge[cnt].w=0;edge[cnt].nxt=head[v];head[v]=cnt; } inline void add(int u,int v){for(int i=head[u];i!=-1;i=edge[i].nxt)if(edge[i].to==v)return;du[u]--;du[v]++;adde(u,v,INF-1); } bool bfs(int m){int r;for(int i=1;i<=m;i++){cur[i]=head[i];lev[i]=-1;}dui[r=0]=S;lev[S]=0;for(int i=0;i<=r;i++){int u=dui[i];for(int j=head[u];j!=-1;j=edge[j].nxt){int v=edge[j].to,w=edge[j].w;if(lev[v]==-1&&w){lev[v]=lev[u]+1;dui[++r]=v;if(v==T)return 1;}}}return 0; } int dinic(int u,int flow,int m){if(u==m)return flow;int res=0,delta;for(int &i=cur[u];i!=-1;i=edge[i].nxt){int v=edge[i].to;if(lev[v]>lev[u]&&edge[i].w){delta=dinic(v,min(flow,edge[i].w),m);if(delta){edge[i].w-=delta;edge[i^1].w+=delta;res+=delta;if(res==flow)break;}}}if(res!=flow)lev[u]=-1;return res; } void build(){ok[n]=1;for(int i=1;i<=l2;i++){int sz=ty[i].size();for(int j=0;j<sz;j++){int I=ty[i][j];if(!ok[I])continue;for(int k=0;k<j;k++){int J=ty[i][k];int K1=to[0][J],K2=to[1][J],K3=to[2][J];if(K1&&f[K1]+sz-k==f[I])add(J,K1),ok[K1]=1;if(K2&&f[K2]+sz-k==f[I])add(J,K2),ok[K2]=1;if(K3&&f[K3]+sz-k==f[I])add(J,K3),ok[K3]=1;}for(int k=j+1;k<sz;k++){int J=ty[i][k];int K1=to[0][J],K2=to[1][J],K3=to[2][J];if(K1&&f[K1]+k+1==f[I])add(J,K1),ok[K1]=1;if(K2&&f[K2]+k+1==f[I])add(J,K2),ok[K2]=1;if(K3&&f[K3]+k+1==f[I])add(J,K3),ok[K3]=1;}int K1=to[0][I],K2=to[1][I],K3=to[2][I];if(K1&&f[K1]+1==f[I])add(I,K1),ok[K1]=1;if(K2&&f[K2]+1==f[I])add(I,K2),ok[K2]=1;if(K3&&f[K3]+1==f[I])add(I,K3),ok[K3]=1;}} } void work2(){memset(head,-1,sizeof(head));cnt=-1;build();S=n+1,T=S+1;int ans=0;for(int i=1;i<=n;i++){if(du[i]>0)adde(S,i,du[i]),ans+=du[i];else if(du[i]<0)adde(i,T,-du[i]);}while(bfs(T))ans-=dinic(S,INF,T);printf("%d\n",ans); } int main(){n=read();for(int i=1;i<=n;i++){p[i].x=b[++l1]=read();p[i].y=c[++l2]=read();p[i].b1=d[++l3]=p[i].y-p[i].x;p[i].b2=e[++l4]=p[i].y+p[i].x;p[i].id=i;}p[++n].x=b[++l1]=0;p[n].y=c[++l2]=0;p[n].b1=d[++l3]=0;p[n].b2=e[++l4]=0;p[n].id=n;work1();work2();return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
转载于:https://www.cnblogs.com/luyouqi233/p/9140050.html
BZOJ4200 洛谷2304 UOJ132:[NOI2015]小园丁与老司机——题解相关推荐
- P2304 [NOI2015] 小园丁与老司机(网络流/上下界网络流)
P2304 [NOI2015] 小园丁与老司机 平面上有n个点,每次可以向左.右.上.左上45度.右上45度移动,然后直线移动到达第一个没有到过的点,如果没有这样的点就不能移动,求解一条最长路,然后求 ...
- 洛谷入门1【顺序结构】题单题解
目录 超级玛丽 字母转换 数字反转 再分肥皂水 小鱼的游泳时间 小学数学N合1 三角形面积 苹果和虫子 对角线 上学迟到 [入门1]顺序结构 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu ...
- 洛谷 P1494 [国家集训队]小Z的袜子
题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编 ...
- 洛谷P1494 [国家集训队]小Z的袜子
P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- ...
- 洛谷 P4823 [TJOI2013]拯救小矮人
题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从 ...
- 洛谷 P1878 舞蹈课 —— 小顶堆
This way 题意: 有 n个人参加一个舞蹈课.每个人的舞蹈技术由整数来决定.在舞蹈课的开始,他们从左到右站成一排.当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞.如果 ...
- 洛谷P2498 [SDOI2012]拯救小云公主 【二分 + 并查集】
题目 英雄又即将踏上拯救公主的道路-- 这次的拯救目标是--爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等级1 ...
- 洛谷P1494 [国家集训队]小Z的袜子 莫队
题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编 ...
- 洛谷P1912:诗人小G(二分栈、决策单调性)
二分栈,就是通过二分维护的栈 (逃) 解析 本题的决策单调性可以说是显然 但是本题是同维度(其实只有一维)自左向右转移,分治的写法是不能奏效的 所以我们使用决策点调性的另一种实现方法:二分栈 具体来说 ...
最新文章
- Curl中的参数知多少
- python【力扣LeetCode算法题库】—两数之和
- 偷天换日——新型浏览器劫持木马“暗影鼠”分析
- vscode怎么设置打开新的文件而不会关闭原来文件
- Flask实战2问答平台--导航条
- 在asp.net 中应用POST传递和接收XML文件以及参数.
- python常用类型的内置函数列表
- java获取系统当前时间格式化_java 获取系统当前时间并格式化
- Matlab Tricks(四)—— remove DC
- ***php调试总结
- pscad仿真数据提取方法
- vax_patch.exe谁有这个文件,可以免费分享一下嘛?
- SpringBoot专栏:集成定时ScheduledTasks任务,刷新概念了_14讲
- “2.17亿中国电信”拿下国家税务局云平台项目,H3C却是最大赢家
- 从零开始构建一个高可靠的RabbitMQ镜像集群
- 2022华为杯A题思路分析移动场景超分辨定位问题
- 小家伙的第一次露营体验
- linux 超级终端
- 微信小程序学习之路——浮动与定位
- 移动端前端UI库—Frozen UI、WeUI、SUI Mobile
热门文章
- MAC快速查看本地 SSH KEY
- Druid在有赞的实践
- 2018年2月Ivanti英万齐(前LANDESK蓝代斯克)关闭中国研发中心
- Oracle as 10g安裝問題
- 如何挑选适合自己的笔记本电脑
- 用python实现bt下载_Python边学边用--BT客户端实现之(一)BitTorrent文件解析
- 不能装载文档控件。请在检查浏览器的选项中检查浏览器的安全设置_「初级会计报考指南」浏览器问题解决方案...
- jQuery实现悬浮窗口
- 1、VS2019配置glfw和glad
- 为什么我说“设计模式”的设计理念是误人子弟?