1019C Sergey's problem(思维)

题意:

找出来一个点集S  使得S中的点不能互相通过一步到达

 并且S中的点 可以在小于等于2的步数下到达所有的点

 要父结点 不要子结点 这样就求出来一个点集S‘  而S'中可能存在 v -> u 这样的路

 所以从后向前遍历 结点 把S’中的点的子结点且在S‘中的点  再从S'中去除掉

  关于为什么从后向前 而不是从前向后 :

  因为S’中剩余的是 v -> u  从后向前可以保证隔一个标记一个

  而从前向后的话 可能使得S‘中的点到达其它点的步数大于二 画图想一下就出来了

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1e6 + , INF = 0x7fffffff;
int head[maxn], vis[maxn], chose[maxn];
int cnt;
vector<int> v;
struct node
{
int u, v, next;
}Node[maxn]; void add(int u, int v)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].next = head[u];
head[u] = cnt++;
} int main()
{
int n, m;
mem(head, -);
cnt = ;
scanf("%d%d", &n, &m);
int a, b;
for(int i=; i<m; i++)
{
scanf("%d%d", &a, &b);
add(a, b);
}
for(int i=; i<=n; i++)
{
if(!vis[i])
{
vis[i] = , chose[i] = ;
for(int j=head[i]; j!=-; j=Node[j].next)
{
node e = Node[j];
vis[e.v] = ;
}
}
}
for(int i=n; i>; i--)
if(chose[i]) for(int j=head[i]; j!=-; j=Node[j].next)
{
node e = Node[j];
chose[e.v] = ;
}
int res = ;
for(int i=; i<=n; i++) if(chose[i]) res++;
cout<< res <<endl;
int ans = ;
for(int i=; i<=n; i++) if(chose[i])
if(ans++) cout<< " " << i;
else cout<< i ; cout<<endl; return ;
}
上一篇:[Python学习笔记]组织文件


下一篇:this作用范围