https://vijos.org/p/1626

描述

“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”

在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。

如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。

现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。

格式

输入格式

第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。

第2到第M+1行,每行两个数A、B,代表A爱B。

输出格式

第1行,一个数,代表爱的国度里有多少爱心天使。

第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。

样例1

样例输入1

6 7
1 2
2 3
3 2
4 2
4 5
5 6
6 4

样例输出1

2
2 3

样例2

样例输入2

3 3
1 2
2 1
2 3

样例输出2

1
-1

限制

各个测试点1s

提示

对于40%的数据 N<=10 M<=100
对于80%的数据 N<=100 M<=1000
对于100%的数据 N<=1000 M<=10000

来源

Cai0715 原创
NOIP 2009·Dream Team 模拟赛 第一期 第四题

描述里的 “如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的” 的 或 应该是 和

不会自爱->原图里不会有独立点

第一问就是 缩点后新点个数 ,第二问 被所有人爱->出度为0 (要注意新图 出现 爱心天使自爱的情况)~~~

 #include <algorithm>
#include <cstdio> using namespace std; const int N(*);
int n,m,u,v; int head[N],sumedge;
struct Edge
{
int u,v,next;
Edge(int u=,int v=,int next=):
u(u),v(v),next(next){}
}edge[N<<];
void ins(int u,int v)
{
edge[++sumedge]=Edge(u,v,head[u]);
head[u]=sumedge;
} int dfn[N],low[N],tim;
int Stack[N],instack[N],top;
int point[N],col[N],sumcol;
void DFS(int now)
{
low[now]=dfn[now]=++tim;
Stack[++top]=now;instack[now]=;
for(int i=head[now];i;i=edge[i].next)
{
int to=edge[i].v;
if(instack[to]) low[now]=min(low[now],dfn[to]);
else if(!dfn[to])
DFS(to),low[now]=min(low[now],low[to]);
}
if(low[now]==dfn[now])
{
col[now]=++sumcol;
point[sumcol]++;
for(;Stack[top]!=now;top--)
{
int Top=Stack[top];
col[Top]=sumcol;
instack[Top]=;
point[sumcol]++;
}
instack[now]=;top--;
}
} int if_,ans,cn,cnt,an[N],s[N],cd[N]; int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d",&u,&v),ins(u,v);
for(int i=;i<=n;i++)
if(!dfn[i]) DFS(i);
for(int i=;i<=m;i++)
if(col[edge[i].u]!=col[edge[i].v])
cd[col[edge[i].u]]++;
for(int i=;i<=sumcol;i++)
{
if(point[i]>&&!cd[i]) s[++cn]=i;
if(point[i]>) ans++;
}
printf("%d\n",ans);
if(cn==)
{
for(int i=;i<=n;i++)
if(col[i]==s[cn]) an[++cnt]=i;
sort(an+,an+cnt+);
for(int i=;i<=cnt;i++)
printf("%d ",an[i]);
if_=;
}
if(!if_) printf("-1\n");
return ;
}
05-25 10:38