[BZOJ 1804] Flood
Link:
Solution:
不容易啊,第一道完全自己A掉的IOI题目.....
算法思想其实很简单:
模拟缩减的过程即可
将每条边转为2条有向边,每次找到最左边的边,沿着最外圈走一周,并将走过的边打上$vis$标记
最后那些正向和反向都被走过的边就是能留下的边(最后形成链的边)
难点在于如何实现在最外层走一周:
由于这是一个平面图,我们对每个点只要记录上下左右四个方向的边即可
又保证是顺时针转,因此尽量往左边走就能满足最外圈这个条件
(注意对$vis$数组更新的位置,否则可能在遇到链时死循环)
其实还有一种不带$log$的做法:
将平面图转化为对偶图,$bfs$每条边到边界的距离
如果两边的距离相等,这条边就计入答案(难点在建图)
待填坑
Code:
#include <bits/stdc++.h> using namespace std;
typedef pair<int,int> P;
#define X first
#define Y second
const int MAXN=4e5+; P nd[MAXN],tp[MAXN];
int n,m,dir[MAXN][],cnt[MAXN][],vis[MAXN][],res=;
int tot=,tdir[MAXN];
struct edge{int x,y,dir;} e[*MAXN];
bool cmp(edge a,edge b) //对边的排序
{
if(nd[a.x].X==nd[b.x].X)
if((a.dir== || a.dir==) && (b.dir== || b.dir==)) return true;
else if((a.dir== || a.dir==) && (b.dir== || b.dir==)) return false;
return nd[a.x].X<nd[b.x].X;
} void add_edge(int a,int b,int id)
{
if(nd[a].X==nd[b].X)
if(nd[a].Y<nd[b].Y) dir[a][]=b,dir[b][]=a,e[id].dir=;
else dir[a][]=b,dir[b][]=a,e[id].dir=;
else
if(nd[a].X<nd[b].X) dir[a][]=b,dir[b][]=a,e[id].dir=;
else dir[a][]=b,dir[b][]=a,e[id].dir=;;
} int Back(int x){return (x+)%;}
int Left(int x){return (x+)%;}
int Right(int x){return (x+)%;}
void Travel(int id)
{
int cur=e[id].y,d=e[id].dir,pre=e[id].x;cnt[pre][d]++;
tot=;tp[tot]=P(pre,cur);tdir[tot]=d;
while(cur!=e[id].x)
{
d=Left(d); //尽量往左走
while(!dir[cur][d] || vis[cur][d]) d=Right(d);
pre=cur;cur=dir[cur][d];cnt[pre][d]++;
tp[++tot]=P(pre,cur);tdir[tot]=d;
}
for(int i=;i<=tot;i++) //一定要最后一起打vis标记,否则可能死循环
vis[tp[i].X][tdir[i]]=vis[tp[i].Y][Back(tdir[i])]=true;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d%d",&nd[i].X,&nd[i].Y);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&e[i].x,&e[i].y);
if(nd[e[i].x].X>nd[e[i].y].X) swap(e[i].x,e[i].y);
if(nd[e[i].x].Y>nd[e[i].y].Y) swap(e[i].x,e[i].y);
add_edge(e[i].x,e[i].y,i);
} sort(e+,e+m+,cmp);
for(int i=;i<=m;i++)
{
if(vis[e[i].x][e[i].dir]) continue; //已走过的边
Travel(i);
}
for(int i=;i<=m;i++)
if(cnt[e[i].x][e[i].dir] && cnt[e[i].y][Back(e[i].dir)]) res++;
printf("%d",res);
return ;
}
Review:
遇到平面图时(保证边两两不相交),一定要考虑其对偶图
[BZOJ 1804] Flood的更多相关文章
- 【BZOJ】初级水题列表——献给那些想要进军BZOJ的OIers(自用,怕荒废了最后的六月考试月,刷刷水题,水水更健康)
BZOJ初级水题列表——献给那些想要进军BZOJ的OIers 代码长度解释一切! 注:以下代码描述均为C++ RunID User Problem Result Memory Time Code_Le ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- SYN Flood测试
由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
随机推荐
- 【COGS 14】 [网络流24题] 搭配飞行员 网络流板子题
用网络流水二分图的模型(存一下板子) #include <cstdio> #include <cstring> #include <algorithm> #defi ...
- Codeforces Round #531 (Div. 3) ABCDEF题解
Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...
- 原生toolbar基本使用教程
1.先写布局文件 <android.support.v7.widget.Toolbar android:id="@+id/toolbar" app:title=" ...
- Equal Sums (map的基本应用) 多学骚操作
C. Equal Sums time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- elk,centos7,filebeat,elasticsearch-head详细安装步骤
先来张图,大致结构应该晓得,对吧! 安装jdk:至少1.8以上 yum -y localinstall jdk-8u73-linux-x64.rpm 安装elasticsearch5.2.1 用普通用 ...
- 图片上传是否为空,以及类型的js验证
function check2() { var file = document.getElementsByName("file").value; if(file=="&q ...
- Notepad++64插件安装方法
首先通过https://github.com/bruderstein/nppPluginManager/releases下载"nppPluginManager",下载解压后放到对应 ...
- LABVIEW伺服电机测试平台
遇见的关键问题总结: 怎么发脉冲:(1)保持电平一段时间进行翻转(2)仿真脉冲 怎样测试脉冲数:通过检测当前时刻和前一时刻的电平是否相同(通过反馈或者移位寄存器实现)来检测脉冲跳变 通过编码器测量速度 ...
- [BZOJ1391]解题报告|网络流的又一类建图&Dinic的若干优化
1391: [Ceoi2008]order 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数, ...
- ssh保持连接
转载自: http://www.neatstudio.com/show-625-1.shtml http://www.linuxidc.com/Linux/2010-05/26031.htm (这一篇 ...