[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个非负整数 ...
随机推荐
- taotao购物车
功能分析: 1.在用户不登陆的情况下也可以使用购物车,那么就需要把购物车信息放入cookie中. 2.可以把商品信息,存放到pojo中,然后序列化成json存入cookie中. 3.取商品信息可以从c ...
- ng 构建
1.ng 构建和部署 构建:编译和合并ng build 部署:复制dist里面的文件到服务器 2.多环境的支持 配置环境package.json "scripts": { &quo ...
- bzoj4589 FWT xor版本
4589: Hard Nim Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 865 Solved: 484[Submit][Status][Disc ...
- Installing Jenkins to Centos Docker
1.Install Docker CE to Centos7 [root@zoo1 ~]# yum install -y yum-utils device-mapper-persistent-data ...
- TypeScript+Vue初体验Demo
github: https://github.com/lanleilin/Typescript-Vue-Demo
- Spring - IoC(8): 基于 Annotation 的配置
除了基于 XML 的配置外,Spring 也支持基于 Annotation 的配置.Spring 提供以下介个 Annotation 来标注 Spring Bean: @Component:标注一个普 ...
- 用户线程 (User Thread)、守护线程 (Daemon Thread)
在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...
- 【BZOJ】5028: 小Z的加油店
[算法]数学+线段树/树状数组 [题解] 首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd. 这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数. 套路:g ...
- 【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)
题目链接 emmm看起来好像无从下手, \(l_i,r_i\)这么大,肯定是要离散化的. 然后我们是选\(m\)个区间,我们先对这些区间按长度排个序也不影响. 排序后,设我们取的\(m\)个区间的编号 ...
- [bzoj2038][2009国家集训队]小Z的袜子(hose)——莫队算法
Brief Description 给定一个序列,您需要处理m个询问,每个询问形如[l,r],您需要回答在区间[l,r]中任意选取两个数相同的概率. Algorithm Design 莫队算法入门题目 ...