博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2689 : 堡垒
阅读量:4677 次
发布时间:2019-06-09

本文共 905 字,大约阅读时间需要 3 分钟。

问题等价于每个三角形里至少选择两个点。

考虑拓扑,每次取出度数为$2$的点$x$,代表一个只与最多一个三角形相邻的三角形$(x,y,z)$。

如果$x$已选,那么$(x,y)$以及$(x,z)$都已经被覆盖,无需再选其它点。

否则因为至少要选两个点,选$y$和$z$一定最优。

时间复杂度$O(n)$。

 

#include
const int N=100010;int n,i,x,y,z,d[N],g[N],v[N<<2],nxt[N<<2],ed,vis[N],h,t,q[N],ans,f[N];inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}inline void add(int x,int y){d[x]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}int main(){ read(n); for(i=1;i<=n+n-3;i++)read(x),read(y),add(x,y),add(y,x); for(h=i=1;i<=n;i++)if(d[i]==2)q[++t]=i; while(h<=t){ x=q[h++]; if(d[x]!=2)continue; vis[x]=1,y=0; for(i=g[x];i;i=nxt[i])if(!vis[v[i]]){ if(y)z=v[i];else y=v[i]; if((--d[v[i]])==2)q[++t]=v[i]; } if(!f[x])f[y]=f[z]=1; } for(i=1;i<=n;i++)ans+=f[i]; return printf("%d",ans),0;}

  

转载于:https://www.cnblogs.com/clrs97/p/8203664.html

你可能感兴趣的文章
八LWIP学习笔记之用户编程接口(NETCONN)
查看>>
Git Day02,工作区,暂存区,回退,删除文件
查看>>
Windows Phone 7 Coding4Fun控件简介
查看>>
Nginx 常用命令总结
查看>>
hall wrong behavior
查看>>
Markdown test
查看>>
Collection集合
查看>>
【C++】const在不同位置修饰指针变量
查看>>
github新项目挂历模式
查看>>
编写jquery插件
查看>>
敏捷开发笔记
查看>>
css实现背景图片模糊
查看>>
学前班
查看>>
手把手教您扩展虚拟内存
查看>>
android-samples-mvp
查看>>
oracle 11g r2安装
查看>>
关于自关联1
查看>>
存储控制器、MMU、flash控制器介绍
查看>>
hdu-1814(2-sat)
查看>>
自我反省
查看>>