原文链接https://www.cnblogs.com/zhouzhendong/p/CF1019C.html

题目传送门 - CF1019C

题意

  给定一个有 $n$ 个节点 、 $m$ 条边的有向图,没有自环,但是可能存在环。

  现在要求选出一个点集满足一下条件。

  设原来的所有点构成的点集为 $V$ ,选出的点集为 $S$,则:

  1. 对于所有满足 $x,y\in S$ 的点 $x,y$ ,有向边 $(x,y)$ 不存在。

  2. 对于所有满足 $y\in V$ 的点,都可以找到一个点 $x(x\in S)$,满足从点 $x$ 开始走到 $y$ 的最少经过边数不超过 2 。

  首先输出你选出的点数,然后按照编号从小到大输出你选的点。

  $n,m\leq 10^6$

题解

  我们考虑以下构造方案:

  1. 记当前的图为 $G(V,E)$ 。

  2. 选择一个节点 $A\in V$ ,从 $G$ 中删除节点 $A$ ,以及从 $A$ 出发的有向边连向的所有节点,得到新图 $G^\prime$ 。

  3. 如果 $V^\prime \neq \emptyset $ ,则返回第 1. 步。否则到第 4 步。

  4. 记之前选出的所有节点 $A$ 构成的集合为 $v$ ,取 $v$ 和 原图 $G$ 中只与 $v$ 中的点有关边集 $e$ ,构成新图 $g(v,e)$ 。容易得知,$g$ 是一个有向无环图。

  5. 记当前的图为 $g(v,e)$ 。

  6. 取一个入度为 $0$ 的节点 $a$ ,并将该节点加入答案集合 $S$,删除 $a$ 以及在 $g$ 中 $a$ 能一步走到的所有点。设得到的新图的点集为 $v^\prime$ 。

  7. 如果 $v^\prime \neq \emptyset$ ,则返回第 1. 步。否则输出答案集合 $S$ 。

  现在简单的说明一下这样做的正确性:

    ① 首先,显然任意两个属于答案集合点不能一步到达。

    ② 对于任意满足 $x\in v,x\notin S$ 的节点 $x$ ,它只可能在第 6 步被删除,那么,显然有一个能一步达到 $x$ 的节点被记入答案。

    ③ 对于任意满足 $x\in V,x\notin v$ 的节点 $x$ ,它只可能在第 2 步的时候被删除,那么,显然有一个能一步到达 $x$ 的节点 $y$ 在集合 $v$ 中。又根据 ② ,如果 $y\notin S$ ,有一步到 $y$ 的节点,则 $x$ 可以花两步到达;否则,$y\in S$ ,$x$ 可以由 $y$ 一步到达。

    ④ 由于属于答案集合的节点显然可以在 2 步以内到达,再根据 ②③ ,上述做法的正确性显然。

  接下来就只差一个方便的实现方法了,详见代码。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1000005;
int read(){
int x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
void write(int v){
int k=v/10;
if (v>9)
write(k);
putchar('0'+(v-k*10));
}
struct Gragh{
static const int M=1000005;
int cnt,y[M],nxt[M],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m;
int vis[N],ans[N],anscnt=0;
int main(){
n=read(),m=read();
g.clear();
for (int i=1;i<=m;i++){
int a=read(),b=read();
g.add(a,b);
}
for (int i=1;i<=n;i++)
if (!vis[i]){
vis[i]=-2;
for (int j=g.fst[i];j;j=g.nxt[j])
vis[g.y[j]]=min(vis[g.y[j]],-1);
}
for (int i=n;i>=1;i--)
if (vis[i]==-2){
ans[++anscnt]=i;
for (int j=g.fst[i];j;j=g.nxt[j])
vis[g.y[j]]=-1;
}
write(anscnt),puts("");
for (int i=anscnt;i>=1;i--)
write(ans[i]),putchar(' ');
return 0;
}

  

Codeforces 1019C Sergey's problem 构造的更多相关文章

  1. [CF1019C]Sergey's problem[构造]

    题意 找出一个集合 \(Q\),使得其中的点两两之间没有连边,且集合中的点可以走不超过两步到达其他所有不在集合中的点.输出任意一组解. \(n\leq 10^6\) 分析 考虑构造,先从 \(1\) ...

  2. 1019C Sergey's problem(思维)

    题意: 找出来一个点集S  使得S中的点不能互相通过一步到达 并且S中的点 可以在小于等于2的步数下到达所有的点 要父结点 不要子结点 这样就求出来一个点集S‘  而S'中可能存在 v -> u ...

  3. Codeforces Round #503 (by SIS, Div. 2) E. Sergey's problem

    E. Sergey's problem [题目描述] 给出一个n个点m条边的有向图,需要找到一个集合使得1.集合中的各点之间无无边相连2.集合外的点到集合内的点的最小距离小于等于2. [算法] 官方题 ...

  4. Educational Codeforces Round 10 B. z-sort 构造

    B. z-sort 题目连接: http://www.codeforces.com/contest/652/problem/B Description A student of z-school fo ...

  5. Codeforces 707C Pythagorean Triples(构造三条边都为整数的直角三角形)

    题目链接:http://codeforces.com/contest/707/problem/C 题目大意:给你一条边,问你能否构造一个包含这条边的直角三角形且该直角三角形三条边都为整数,能则输出另外 ...

  6. Codeforces 1246D/1225F Tree Factory (构造)

    题目链接 https://codeforces.com/contest/1246/problem/D 题解 首先考虑答案的下界是\(n-1-dep\) (\(dep\)为树的深度,即任何点到根的最大边 ...

  7. Codeforces - 1202D - Print a 1337-string... - 构造

    https://codeforces.com/contest/1202/problem/D 当时想的构造是中间两个3,然后前后的1和7组合出n,问题就是n假如是有一个比较大的质数因子或者它本身就是质数 ...

  8. [codeforces 528]B. Clique Problem

    [codeforces 528]B. Clique Problem 试题描述 The clique problem is one of the most well-known NP-complete ...

  9. codeforces.com/contest/325/problem/B

    http://codeforces.com/contest/325/problem/B B. Stadium and Games time limit per test 1 second memory ...

随机推荐

  1. MVC、MVP、MVVM模式

    MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...

  2. minicom的配置和使用

    安装配置minicom--------------------------------------------------# lsmod | grep usbserial (如果直接使用串口线,而没有 ...

  3. kafka集群报错

    bin/kafka-server-start.sh config/server.properties ,问题来了 : [root@localhost kafka_2.12-0.10.2.0]# Exc ...

  4. LuoGu P1083 借教室

    题目传送门 借教室这个题有两种做法,差分+前缀和或者是线段树 线段树维护区间最小值,因为能不能借教室使用是由这几天中可用教室最少的一天决定的 其实这题是个很裸的线段树维护区间最小值,但有一点需要注意, ...

  5. iOS 上线过程中出现的问题总结

    1:  因为使用后台播放音乐,在 info 里面添加 required background modes  的 key, 如果你的代码里面没有后套播放音频的功能, 不要添加 required back ...

  6. redis-cluster集群搭建

     Redis3.0版本之前,可以通过Redis Sentinel(哨兵)来实现高可用 ( HA ),从3.0版本之后,官方推出了Redis Cluster,它的主要用途是实现数据分片(Data Sha ...

  7. laravel 中with关联查询限定查询字段

    学习了下laravel5.6框架,果然很优雅,比如ActiveJieSuan model中作如下关联:(laravel模型关联关系可以查看https://laravelacademy.org/post ...

  8. HTML&javaSkcript&CSS&jQuery&ajax(四)

    一.HTML创建响应设计 Responsive Web Design 可以改变尺寸传递网页,对于平板和移动设备是必须的 1.<!DOCTYPE html><html lang=&qu ...

  9. hdu3635

    /* 一开始第a个球在第a个城市 操作T a b,把第a个球所在城市的所有球移到b所在的城市 操作Q a 要求输出 第a个球在哪个城市 第a个球所在的城市有几个球 第a个球移动次数 */ #inclu ...

  10. C++ 使用system()实现锁定屏幕

    除了使用函数“LockWorkStation()”实现锁定屏幕,参考:http://www.cnblogs.com/Satu/p/8183081.html 此外,也可以使用函数“system()”来实 ...