博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
牛的障碍Cow Steeplechase
阅读量:5115 次
发布时间:2019-06-13

本文共 4438 字,大约阅读时间需要 14 分钟。

题目描述

Farmer John has a brilliant idea for the next great spectator sport: Cow Steeplechase! As everyone knows, regular steeplechase involves a group of horses that race around a course filled with obstacles they must jump over. FJ figures the same contest should work with highly-trained cows, as long as the obstacles are made short enough.

In order to design his course, FJ makes a diagram of all the N (1 <= N <= 250) possible obstacles he could potentially build. Each one is represented by a line segment in the 2D plane that is parallel to the horizontal or vertical axis. Obstacle i has distinct endpoints (X1_i, Y1_i) and (X2_i, Y2_i) (1 <= X1_i, Y1_i, X2_i, Y2_i <= 1,000,000,000). An example is as follows:

--+-------   -----+-----  ---+---     |     |     |  |   --+-----+--+-   |     |     |  |  | |     |   --+--+--+-+-           |  |  | |              |

FJ would like to build as many of these obstacles as possible, subject to the constraint that no two of them intersect. Starting with the diagram above, FJ can build 7 obstacles:

----------   -----------  -------     |           |  |           |  |    |           |  |  | |           |  |  | |           |  |  | |              |

Two segments are said to intersect if they share any point in common, even an endpoint of one or both of the segments. FJ is certain that no two horizontal segments in the original input diagram will intersect, and that similarly no two vertical segments in the input diagram will intersect.

Please help FJ determine the maximum number of obstacles he can build.

给出N平行于坐标轴的线段,要你选出尽量多的线段使得这些线段两两没有交点(顶点也算),横的与横的,竖的与竖的线段之间保证没有交点,输出最多能选出多少条线段。

输入输出格式

输入格式:

* Line 1: A single integer: N.

* Lines 2..N+1: Line i+1 contains four space-separated integers representing an obstacle: X1_i, Y1_i, X2_i, and Y2_i.

输出格式:

* Line 1: The maximum number of non-crossing segments FJ can choose.

输入输出样例

输入样例#1:

3 4 5 10 5 6 2 6 12 8 3 8 5

输出样例#1:

2

Solution

网络流,正难则反,明显可以看出的是,我们可以把交叉的线段之间连边然后就可以求出最大匹配,这也就是我们需要去掉的线段的数目。一道入门题目?然而蒟蒻做了一个小时。。。

Code

#pragma comment(linker, "/STACK:1024000000,1024000000")#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define re registerusing namespace std;typedef long long ll;typedef unsigned long long ull;#define ms(arr) memset(arr, 0, sizeof(arr))const int inf = 0x3f3f3f3f;struct po{ int nxt,to,w;}edge[200001];struct point{ int x1,x2,y1,y2,id;}a[200001];int head[252],dep[252],s,t,n,m,num=-1,cur[2000001],sum;inline int read(){ int x=0,c=1; char ch=' '; while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); while(ch=='-') c*=-1,ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*c;}inline void add_edge(int from,int to,int w){ edge[++num].nxt=head[from]; edge[num].to=to; edge[num].w=w; head[from]=num;}inline void add(int from,int to,int w){ add_edge(from,to,w); add_edge(to,from,0);}inline bool bfs(){ memset(dep,0,sizeof(dep)); queue
q; while(!q.empty()) q.pop(); q.push(s); dep[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(re int i=head[u];i!=-1;i=edge[i].nxt) { int v=edge[i].to; if(dep[v]==0&&edge[i].w>0) { dep[v]=dep[u]+1; if(v==t) return 1; q.push(v); } } } return 0;}inline int dfs(int u,int dis){ if(u==t) return dis; int diss=0; for(re int& i=cur[u];i!=-1;i=edge[i].nxt) { int v=edge[i].to; if(edge[i].w!=0&&dep[v]==dep[u]+1) { int check=dfs(v,min(dis,edge[i].w)); if(check!=0) { dis-=check; diss+=check; edge[i].w-=check; edge[i^1].w+=check; if(dis==0) break; } } } return diss;}inline int dinic(){ int ans=0; while(bfs()) { for(re int i=0;i<=n;i++) cur[i]=head[i]; while(int d=dfs(s,inf)) ans+=d; } return ans;}int main(){ memset(head,-1,sizeof(head)); n=read(); s=0;t=n+1; for(re int i=1;i<=n;i++){ int x1,y1,x2,y2; x1=read();y1=read();x2=read();y2=read(); if(x1>x2) swap(x1,x2);if(y1>y2) swap(y1,y2); a[i].x1=x1;a[i].y1=y1;a[i].x2=x2;a[i].y2=y2; if(a[i].x1==a[i].x2) a[i].id=1; else a[i].id=2; } for(re int i=1;i<=n;i++){ if(a[i].id==1){ int H=a[i].x1;add(s,i,1); for(re int j=i+1;j<=n;j++){ if(a[j].id==2&&a[j].x1<=H&&a[j].x2>=H&&a[i].y1<=a[j].y1&&a[i].y2>=a[j].y2){ add(i,j,1); sum++; } } }else { add(i,t,1); int L=a[i].y1; for(re int j=i+1;j<=n;j++){ if(a[j].id==1&&a[j].y1<=L&&a[j].y2>=L&&a[i].x1<=a[j].x1&&a[i].x2>=a[j].x2){ add(j,i,1); sum++; } } } } int d=dinic(); cout<

转载于:https://www.cnblogs.com/victorique/p/9004544.html

你可能感兴趣的文章
CocoaPods的安装和使用那些事(Xcode 7.2,iOS 9.2,Swift)
查看>>
Android 官方新手指导教程
查看>>
幸运转盘v1.0 【附视频】我的Android原创处女作,请支持!
查看>>
UseIIS
查看>>
集合体系
查看>>
vi命令提示:Terminal too wide
查看>>
引用 移植Linux到s3c2410上
查看>>
MySQL5.7开多实例指导
查看>>
[51nod] 1199 Money out of Thin Air #线段树+DFS序
查看>>
poj1201 查分约束系统
查看>>
Red and Black(poj-1979)
查看>>
分布式锁的思路以及实现分析
查看>>
腾讯元对象存储之文件删除
查看>>
jdk环境变量配置
查看>>
安装 Express
查看>>
包含列的索引:SQL Server索引的阶梯级别5
查看>>
myeclipse插件安装
查看>>
浙江省第十二届省赛 Beauty of Array(思维题)
查看>>
NOIP2013 提高组 Day1
查看>>
个人对vue生命周期的理解
查看>>