CF1019C
好玄学的东西...
核心思想:for循环!
首先,我们从前向后扫所有的点,如果这个点没被标记成不可用就把这个点标记成已使用,然后把所有与这个点直接相连的点标记成不可用
接下来,我们从后向前扫所有的点,如果这个点被标记成已使用就把与这个点所有直接相连的也被标记已使用的点达成不能使用,最后标记成可使用的就是集合中的点
证明一下这个算法的正确性:
首先,经过第一步操作后,第二个要求一定能够满足,因为现在集合中的点和集合外的点的距离至多是1!(如果这个点不在集合里,说明这个点一定已经被一个在集合里的点标记上了,所以集合里的点到集合外的点的距离最大是1)
可是这样做会产生一些不合法的情况,这些情况的产生原因是我们在进行第一步操作时,只能够排除由编号较小的点向编号较大的点连边的情况,但是如果有编号较大的点向编号较小的点连边这种情况是无法处理的
所以我们第二次再从后向前扫点,将与扫到的所有计划使用的点有连边的点标记为不可用,这样就能保证集合中的点互相没有连边了
至于这么做是否能满足距离的要求,我们思考:经过第一步操作后,我们能保证的是所有集合外的点与集合内的点距离为1
那么我们删除一个集合内的点的条件这个点与集合中别的点有连边,也就是说如果这个点被删掉了,这个点与集合的距离就会变成1,那么最糟的情况无非就是另一个集合外的点只与这个点相连,这样的情况的话外面的点到集合的距离无非就是2,所以也是合法的,也就是说,这样操作后获得的情况一定是一种合法情况!
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
struct Edge
{
int next;
int to;
}edge[];
int head[];
bool used[];
bool vis[];
int cnt=;
int n,m;
void init()
{
memset(head,-,sizeof(head));
cnt=;
}
void add(int l,int r)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
head[l]=cnt++;
} int main()
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=;i<=n;i++)
{
if(!used[i])
{
vis[i]=;
used[i]=;
for(int j=head[i];j!=-;j=edge[j].next)
{
int to=edge[j].to;
used[to]=;
}
}
}
for(int i=n;i>=;i--)
{
if(vis[i])
{
for(int j=head[i];j!=-;j=edge[j].next)
{
int to=edge[j].to;
vis[to]=;
}
}
}
int ret=;
for(int i=;i<=n;i++)
{
if(vis[i])
{
ret++;
}
}
printf("%d\n",ret);
for(int i=;i<=n;i++)
{
if(vis[i])
{
printf("%d ",i);
}
}
return ;
}
CF1019C的更多相关文章
- [CF1019C]Sergey's problem[构造]
题意 找出一个集合 \(Q\),使得其中的点两两之间没有连边,且集合中的点可以走不超过两步到达其他所有不在集合中的点.输出任意一组解. \(n\leq 10^6\) 分析 考虑构造,先从 \(1\) ...
- CF1019C Sergey's problem (图上构造)
题目大意:给你一个有向连通图,让你找出一个点集,保证点集内的点之间没有直接连边,且集合中存在一点,到一个 非点集中的点的距离小于等于2 思路很清奇 首先编号从小到大遍历每个点,如果这个点没有被访问过, ...
- Codeforces 1019C Sergey's problem 构造
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1019C.html 题目传送门 - CF1019C 题意 给定一个有 $n$ 个节点 . $m$ 条边的有向 ...
- 【CF1020E】Sergey's problem(构造)
题意: 思路:这是一道论文题 https://link.springer.com/content/pdf/10.1007/BFb0066192.pdf From http://www.cnblogs. ...
随机推荐
- Java的两大数据类型
Java的两大数据类型 基本数据类型 byte,short,int,long,float,double,boolean,char byte 类别 内容 类型 byte 简介 byte 数据类型是8位. ...
- CPU火焰图
y轴:栈深度 x轴:cpu时间 长方形:一个栈(方法) 长度:出现在监视器中的时长(占用cpu的时间) 其他:从左到右的顺序只是按字母排序,无其他意义 火焰图就是看顶层的哪个函数占据的宽度最大.只要有 ...
- Web三层-UI/BLL/DAL/MODEL
2013传智播客视频\视频\2013-05-28-EF\视频 创建4个程序集,添加引用,model添加映射, P01UI表现层--BLL+MODELP02BLL业务层--DAL+MODELP03DAL ...
- 获取汉字拼音&首字母
pinyin4j https://www.cnblogs.com/yjq520/p/7681537.html
- 【多视图几何】TUM 课程 第5章 双视图重建:线性方法
课程的 YouTube 地址为:https://www.youtube.com/playlist?list=PLTBdjV_4f-EJn6udZ34tht9EVIW7lbeo4 .视频评论区可以找到课 ...
- js对象遍历输出顺序错乱的问题
一.js对象遍历顺序错乱的原因 下边就来实践一下: var obj={'3':'ccc',name:'abc',age:23,school:'sdfds',class:'dfd',hobby:'dsf ...
- 基于keepalived搭建MySQL热机集群
背景 MySQL的高可用方案一般有如下几种: keepalived+双主,MHA,MMM,Heartbeat+DRBD,PXC,Galera Cluster 比较常用的是keepalived+双主,M ...
- CF1096D Easy Problem
题目地址:CF1096D Easy Problem 比赛时高二dalaoLRZ提醒我是状压,然而,我还是没AC (汗 其实是一道很基础的线性dp \(f_{i,j}\) 表示序列第 \(i\) 个字符 ...
- lnmp 搭建 初试
#初始化环境检查 # uname -r -.el6.x86_64 # uname -m x86_64 #添加mysql用户 useradd -s /sbin/nologin mysql -M #下载安 ...
- vc++基础班[24]---系统各种路径信息的获取
vc++基础班[24]---系统各种路径信息的获取 ------------------------------------------ Begin ------------------------- ...