BZOJ3630: [JLOI2014]镜面通道
2017-01-23 21:43
375 查看
Description
在一个二维平面上,有一个镜面通道,由镜面AC,BD组成,AC,BD长度相等,且都平行于x轴,B位于(0,0)。通道中有n个外表面为镜面的光学元件,光学元件α为圆形,光学元件β为矩形(这些元件可以与其他元件和通道有交集,具体看下图)。光线可以在AB上任一点以任意角度射入通道,光线不会发生削弱。当出现元件与元件,元件和通道刚好接触的情况视为光线无法透过(比如两圆相切)。现在给出通道中所有元件的信息(α元件包括圆心坐标和半径xi,yi,ri,β元件包括左下角和右上角坐标x1,y1,x2,y2)如上图,S到T便是一条合法线路。
当然,显然存在光线无法透过的情况,现在交给你一个艰巨的任务,请求出至少拿走多少个光学元件后,存在一条光线线路可以从CD射出。
下面举例说明:
现在假设,取走中间那个矩形,那么就可以构造出一条穿过通道的光路,如图中的S到T。
Input
第一行包含两个整数,x,y,表示C点坐标第二行包含一个数字,n,表示有n个光学元件
接下来n行
第一个数字如果是1,表示元件α,后面会有三个整数xi,yi,ri分别表示圆心坐标和半径
第一个数字如果是2,表示元件β,后面会有四个整数x1,y1,x2,y2分别表示左下角和右上角坐标(矩形都平行,垂直于坐标轴)
Output
输出包含一行,至少需要拿走的光学元件个数m
Sample Input
1000 1006
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
Sample Output
2HINT
x<=100000,y<=1000,n<=300Source
网络流首先从上到下如果元件不连通光一定能过去
然后就是裸的最小割
这题难在建图,根本不用想,就是计算几何,写起来23333
判断圆和矩形相交我基本是抄的2333
#include<bits/stdc++.h> using namespace std; const int MAXN = 1110; const int MAXM = 500050; const int INF = 1e9 + 7; int cnt = 1, n, m, ans, S, T, ql, qr; int cur[MAXN], head[MAXN], q[MAXN], dis[MAXN]; struct edge { int to, nxt, flow; }e[MAXM]; inline void add(int x, int y, int w) { e[ ++cnt ].to = y; e[ cnt ].nxt = head[ x ]; head[ x ] = cnt; e[ cnt ].flow = w; } inline void addedge(int x, int y, int w) { add( x, y, w ); add( y, x, 0 ); } inline bool bfs() { memset( dis, 0, sizeof dis ); ql = 0; dis[ q[ qr = 1 ] = S ] = 1; while( ql < qr ) { int x = q[ ++ql ]; for( int i = head[ x ] ; i ; i = e[ i ].nxt ) if( e[ i ].flow&& !dis[ e[ i ].to ] ) dis[ q[ ++qr ] = e[ i ].to ] = dis[ x ] + 1; } return dis[ T ]; } inline int dfs(int x, int flow) { if( x == T ) return flow; int ret = 0; for( int &i = cur[ x ] ; i ; i = e[ i ].nxt ) if( e[ i ].flow && dis[ e[ i ].to ] == dis[ x ] + 1 ) { int d = dfs( e[ i ].to, min( flow - ret, e[ i ].flow ) ); e[ i ].flow -= d; e[ i ^ 1 ].flow += d; ret += d; if( ret == flow ) return flow; } if( !ret ) dis[ x ] = -1; return ret; } inline void dinic() { while( bfs() ) memcpy( cur, head, sizeof cur ), ans += dfs( S, INF ); } inline int read() { int sc = 0, f = 1; char ch = getchar(); while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar(); return sc * f; } struct object { int type, x1, y1, x2, y2, r; inline void scan() { type = read(); if( type == 1 ) x1 = read(), y1 = read(), r = read(); else x1 = read(), y1 = read(), x2 = read(), y2 = read(); } }a[MAXN]; int x, y; inline double sqr(double x) { return x * x; } inline double dist(int x1, int y1, int x2, int y2) { return sqrt( sqr( x2 - x1 ) + sqr( y2 - y1 ) ); } inline bool cross(int p, int q) { if( a[ p ].type == 1 && a[ q ].type == 2 ) return cross( q, p ); if( a[ p ].type == 1 && a[ q ].type == 1 ) { return dist( a[ p ].x1, a[ p ].y1, a[ q ].x1, a[ q ].y1 ) <= a[ p ].r + a[ q ].r; } if( a[ p ].type == 2 && a[ q ].type == 2 ) { return ( max( a[ p ].x1, a[ q ].x1 ) <= min( a[ p ].x2, a[ q ].x2 ) ) && ( max( a[ p ].y1, a[ q ].y1 ) <= min( a[ p ].y2, a[ q ].y2 ) ); } int x1 = a[ p ].x1, y1 = a[ p ].y1, x2 = a[ p ].x2, y2 = a[ p ].y2; int x = a[ q ].x1, y = a[ q ].y1, r = a[ q ].r; if( dist( x, y, x1, y1 ) <= r || dist( x, y, x2, y2 ) <= r || dist( x, y, x1, y2 ) <= r || dist( x, y, x2, y1 ) <= r ) return true; if( x >= x1 && x <= x2 && ( abs( y - y1 ) <= r || abs( y - y2 ) <= r ) ) return true; if( y >= y1 && y <= y2 && ( abs( x - x1 ) <= r || abs( x - x2 ) <= r ) ) return true; return false; } int main() { x = read(); y = read(); n = read(); T = 1; for( int i = 1 ; i <= n ; i++ ) { a[ i ].scan(); addedge( i << 1, i << 1 | 1, 1 ); for( int j = 1 ; j < i ; j++ ) if( cross( i, j ) ) addedge( i << 1 | 1, j << 1, INF ), addedge( j << 1 | 1, i << 1, INF ); if( a[ i ].type == 1 ) { if( a[ i ].y1 - a[ i ].r <= 0 ) addedge( S, i << 1, INF ); if( a[ i ].y1 + a[ i ].r >= y ) addedge( i << 1 | 1, T, INF ); } else { if( a[ i ].y1 <= 0 ) addedge( S, i << 1, INF ); if( a[ i ].y2 >= y ) addedge( i << 1 | 1, T, INF ); } } dinic(); return printf( "%d\n", ans ), 0; }
相关文章推荐
- bzoj3630 [JLOI2014]镜面通道
- 【bzoj 3630】: [JLOI2014]镜面通道
- 【BZOJ3630】[JLOI2014]镜面通道 几何+最小割
- 【bzoj3630】[JLOI2014]镜面通道 对偶图+计算几何+网络流最小割
- bzoj 3630 [JLOI2014]镜面通道 计算几何 网络流
- BZOJ3630 : [JLOI2014]镜面通道
- BZOJ 3630 JLOI2014 镜面通道 计算几何+最小点割集
- BZOJ 3630 JLOI 2013 镜面通道 最小点割集
- bzoj3630: [JLOI2014]镜面通道
- bzoj3630 镜面通道 网络流
- BZOJ3630: [JLOI2014]镜面通道 最小割
- 【约数和公式+DFS】BZOJ3629(JLOI2014)[聪明的燕姿]题解
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分
- 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组
- BZOJ 3631 [JLOI2014]松鼠的新家
- BZOJ3629 [JLOI2014]聪明的燕姿
- BZOJ3631: [JLOI2014]松鼠的新家
- 【BZOJ3631】【JLOI2014】松鼠的新家
- BZOJ 3627 JLOI2014 路径规划 分层图+堆优化SPFA JLOI2014全AC达成!
- BZOJ 3629 [JLOI2014] 聪明的燕姿 dfs