题目描述

在一个二维平面上,有一个镜面通道,由镜面AC,BD组成,AC,BD长度相等,且都平行于x轴,B位于(0,0)。通道中有n个外表面为镜面的光学元件,光学元件α为圆形,光学元件β为矩形(这些元件可以与其他元件和通道有交集,具体看下图)。光线可以在AB上任一点以任意角度射入通道,光线不会发生削弱。当出现元件与元件,元件和通道刚好接触的情况视为光线无法透过(比如两圆相切)。现在给出通道中所有元件的信息(α元件包括圆心坐标和半径xi,yi,ri,β元件包括左下角和右上角坐标x1,y1,x2,y2)

如上图,S到T便是一条合法线路。

当然,显然存在光线无法透过的情况,现在交给你一个艰巨的任务,请求出至少拿走多少个光学元件后,存在一条光线线路可以从CD射出。

下面举例说明:

现在假设,取走中间那个矩形,那么就可以构造出一条穿过通道的光路,如图中的S到T。

输入

第一行包含两个整数,x,y,表示C点坐标

第二行包含一个数字,n,表示有n个光学元件

接下来n行

第一个数字如果是1,表示元件α,后面会有三个整数xi,yi,ri分别表示圆心坐标和半径

第一个数字如果是2,表示元件β,后面会有四个整数x1,y1,x2,y2分别表示左下角和右上角坐标(矩形都平行,垂直于坐标轴)

输出

输出包含一行,至少需要拿走的光学元件个数m

样例输入

1000 100
6
1 500 0 50
2 10 10 20 100
2 100 10 200 100
2 300 10 400 100
2 500 10 600 100
2 700 0 800 100

样例输出

2


题解

对偶图+计算几何+网络流最小割

首先有个神奇的物理学结论:水能通过的地方光也一定能通过。

因此直接判定左右通道是否连通即可。而和 bzoj3007 类似,左右连通意味着对偶图上下不连通。

所以问题转化为去掉最少的点使得上下不连通。这显然是个最小割问题。

拆点,如果两个元件相交,则互相连出点->入点的边,容量为inf;每个点的入点->出点,容量为1。最小割即为答案。

不过有点恶心的是原件相交的判定,需要耐心= =

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 610
#define M 400010
using namespace std;
typedef long long ll;
const int inf = 1 << 30;
queue<int> q;
int flag[N] , a[N] , b[N] , c[N] , d[N] , head[N] , to[M] , val[M] , next[M] , cnt = 1 , s , t , dis[N];
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
ll calc(int x , int y)
{
return (ll)x * x + (ll)y * y;
}
bool judge(int x , int y)
{
if(flag[x] + flag[y] == 2) return calc(a[x] - a[y] , b[x] - b[y]) <= (ll)(c[x] + c[y]) * (c[x] + c[y]);
else if(flag[x] + flag[y] == 3)
{
if(flag[x] == 2) swap(x , y);
if(calc(a[x] - a[y] , b[x] - b[y]) <= (ll)c[x] * c[x]) return 1;
if(calc(a[x] - a[y] , b[x] - d[y]) <= (ll)c[x] * c[x]) return 1;
if(calc(a[x] - c[y] , b[x] - b[y]) <= (ll)c[x] * c[x]) return 1;
if(calc(a[x] - c[y] , b[x] - d[y]) <= (ll)c[x] * c[x]) return 1;
if(abs(a[x] - a[y]) <= c[x] && b[x] >= b[y] && b[x] <= d[y]) return 1;
if(abs(a[x] - c[y]) <= c[x] && b[x] >= b[y] && b[x] <= d[y]) return 1;
if(abs(b[x] - b[y]) <= c[x] && a[x] >= a[y] && a[x] <= c[y]) return 1;
if(abs(b[x] - d[y]) <= c[x] && a[x] >= a[y] && a[x] <= c[y]) return 1;
return 0;
}
else
{
if(a[x] >= a[y] && a[x] <= c[y] && b[y] >= b[x] && b[y] <= d[x]) return 1;
if(a[x] >= a[y] && a[x] <= c[y] && d[y] >= b[x] && d[y] <= d[x]) return 1;
if(b[x] >= b[y] && b[x] <= d[y] && a[y] >= a[x] && a[y] <= c[x]) return 1;
if(b[x] >= b[y] && b[x] <= d[y] && c[y] >= a[x] && c[y] <= c[x]) return 1;
if(c[x] >= a[y] && c[x] <= c[y] && b[y] >= b[x] && b[y] <= d[x]) return 1;
if(c[x] >= a[y] && c[x] <= c[y] && d[y] >= b[x] && d[y] <= d[x]) return 1;
if(d[x] >= b[y] && d[x] <= d[y] && a[y] >= a[x] && a[y] <= c[x]) return 1;
if(d[x] >= b[y] && d[x] <= d[y] && c[y] >= a[x] && c[y] <= c[x]) return 1;
return 0;
}
return 0;
}
int main()
{
int h , n , i , j , ans = 0;
scanf("%*d%d%d" , &h , &n) , s = 0 , t = 2 * n + 2;
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d%d%d%d" , &flag[i] , &a[i] , &b[i] , &c[i]);
add(i + n + 1 , i , 1);
if(flag[i] == 1)
{
if(b[i] + c[i] >= h) add(s , i + n + 1 , inf);
if(b[i] - c[i] <= 0) add(i , t , inf);
}
if(flag[i] == 2)
{
scanf("%d" , &d[i]);
if(d[i] >= h) add(s , i + n + 1 , inf);
if(b[i] <= 0) add(i , t , inf);
}
for(j = 1 ; j < i ; j ++ )
if(judge(i , j))
add(i , j + n + 1 , inf) , add(j , i + n + 1 , inf);
}
while(bfs()) ans += dinic(s , inf);
printf("%d\n" , ans);
return 0;
}

【bzoj3630】[JLOI2014]镜面通道 对偶图+计算几何+网络流最小割的更多相关文章

  1. [bzoj3630][JLOI2014]镜面通道_计算几何_网络流_最小割

    镜面通道 bzoj-3630 JLOI-2014 题目大意:题目链接. 注释:略. 想法: 我们发现,只要上下界没有被完全封死,我们就一定有一条合法的光路. 所以只需要将上界和下界拆开即可. 拆点,把 ...

  2. BZOJ3630 : [JLOI2014]镜面通道

    从左边不能到达右边当且仅当存在一条与上下底边相连的分割线将它们分开 设下底边为S,上底边为T,每个元件作为点,有公共部分的两个点互相连边 最后拆点求最小割 #include<cstdio> ...

  3. 【BZOJ3630】[JLOI2014]镜面通道 几何+最小割

    [BZOJ3630][JLOI2014]镜面通道 Description 在一个二维平面上,有一个镜面通道,由镜面AC,BD组成,AC,BD长度相等,且都平行于x轴,B位于(0,0).通道中有n个外表 ...

  4. 【题解】 bzoj3894: 文理分科 (网络流/最小割)

    bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...

  5. 【bzoj3774】最优选择 网络流最小割

    题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...

  6. 【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割

    题目描述 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河 ...

  7. 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan

    题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...

  8. 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割

    题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...

  9. 【bzoj4177】Mike的农场 网络流最小割

    题目描述 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i] ...

随机推荐

  1. 【BZOJ1833】[ZJOI2010] count 数字计数(数位DP)

    点此看题面 大致题意: 求在给定的两个正整数\(a\)和\(b\)中的所有整数中,\(0\sim9\)各出现了多少次. 数位\(DP\) 很显然,这是一道数位\(DP\)题. 我们可以用前缀和的思想, ...

  2. python_56_递归

    在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.(最大调用自己999次) def calc(n): print(n) if int(n/2)>0: retur ...

  3. python_48_Python3中字符编码与转码

    python3默认是Unicode,不用声明# -*- coding:utf-8 -*-,如果声明则是utf-8 unicode='你好' print('utf-8:',unicode.encode( ...

  4. 【SQL】连接 —— 内连接、外连接、左连接、右连接、交叉连接

    连接 · 内连接 · 外连接 · 左连接 · 右连接 · 全连接 · 交叉连接 · 匹配符号(+)  连接  根据表之间的关系,呈现跨表查询的结果.     外连接     内连接 左连接 右连接 全 ...

  5. nodejs 实现图片上传

    1.首先在目录下的运行cmd,执行以下命令 npm install multer; 2.在router下新建upload.js let express = require('express');let ...

  6. C/C++ 程序基础 (一)基本语法

    域操作符: C++ 支持通过域操作符访问全局变量,C不支持(识别为重定义) ++i和i++的效率分析: 内置类型,无区别 自定义数据类型,++i可以返回引用,i++只能返回对象值(拷贝开销) 浮点数与 ...

  7. PAM认证机制

    PAM:Pluggable Authentication Modules 认证库:文本文件,MySQL,NIS,LDAP等 Sun公司于1995 年开发的一种与认证相关的通用框架机制 PAM 是关注如 ...

  8. MySql学习笔记05

    复习 GROUP BY 语句 HAVING 子句 -- 查询每个分类商品所对应的库存总量中,高于1000的总量 select category_id,sum(num) s from t_item gr ...

  9. nginx修改nginx.conf配置可以https访问

    修改nginx.conf,参照如下更改配置server { listen 443; server_name abc.com; // 访问域名 ssl on; root /var/www/bjubi.c ...

  10. Redux百行代码千行文档

    接触Redux不过短短半年,从开始看官方文档的一头雾水,到渐渐已经理解了Redux到底是在做什么,但是绝大数场景下Redux都是配合React一同使用的,因而会引入了React-Redux库,但是正是 ...