Link:

BZOJ 1804 传送门

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的更多相关文章

  1. 【BZOJ】初级水题列表——献给那些想要进军BZOJ的OIers(自用,怕荒废了最后的六月考试月,刷刷水题,水水更健康)

    BZOJ初级水题列表——献给那些想要进军BZOJ的OIers 代码长度解释一切! 注:以下代码描述均为C++ RunID User Problem Result Memory Time Code_Le ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. SYN Flood测试

    由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...

  5. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  6. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  7. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  8. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  9. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

随机推荐

  1. 【COGS 14】 [网络流24题] 搭配飞行员 网络流板子题

    用网络流水二分图的模型(存一下板子) #include <cstdio> #include <cstring> #include <algorithm> #defi ...

  2. Codeforces Round #531 (Div. 3) ABCDEF题解

    Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...

  3. 原生toolbar基本使用教程

    1.先写布局文件 <android.support.v7.widget.Toolbar android:id="@+id/toolbar" app:title=" ...

  4. Equal Sums (map的基本应用) 多学骚操作

    C. Equal Sums time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. elk,centos7,filebeat,elasticsearch-head详细安装步骤

    先来张图,大致结构应该晓得,对吧! 安装jdk:至少1.8以上 yum -y localinstall jdk-8u73-linux-x64.rpm 安装elasticsearch5.2.1 用普通用 ...

  6. 图片上传是否为空,以及类型的js验证

    function check2() { var file = document.getElementsByName("file").value; if(file=="&q ...

  7. Notepad++64插件安装方法

    首先通过https://github.com/bruderstein/nppPluginManager/releases下载"nppPluginManager",下载解压后放到对应 ...

  8. LABVIEW伺服电机测试平台

    遇见的关键问题总结: 怎么发脉冲:(1)保持电平一段时间进行翻转(2)仿真脉冲 怎样测试脉冲数:通过检测当前时刻和前一时刻的电平是否相同(通过反馈或者移位寄存器实现)来检测脉冲跳变 通过编码器测量速度 ...

  9. [BZOJ1391]解题报告|网络流的又一类建图&Dinic的若干优化

    1391: [Ceoi2008]order 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数, ...

  10. ssh保持连接

    转载自: http://www.neatstudio.com/show-625-1.shtml http://www.linuxidc.com/Linux/2010-05/26031.htm (这一篇 ...