“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢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:
6 7
1 2
2 3
3 2
4 2
4 5
5 6
6 4
样例输入2:
3 3
1 2
2 1
2 3
样例输出1:
2
2 3
样例输出2:
1
-1
各个测试点1s
题解:
已经没法对题目的描述吐槽了… …
题目扯了一大堆就是采用了比喻的手法(出题者也是挺拼的),其实发现了这是一张有向图就好了。
题目要求互相相爱的一组人的组数,就是他们之间连通,也即是强连通分量的个数(其中,结点个数为1的不算),所以就推上Tarjan算法~~~
//由于题目数据太水,直接就水过了。
//附上AC代码,尽情地膜拜我吧
至于找出下一个要求,我们发现,如果这个强连通分量有出度,那么他肯定没有被全部的人(组)喜欢(
因为如果他被所有人喜欢,然后他有喜欢某个人,那么这两个就可以组成一个强连通分量,然而之前已经找过了,所以就排除有出度的组)
#include<iostream>
#include<cstdio>
using namespace std;
struct data{
int to,next;
}e[50001],d[50001];
int n,m,cnt,top;
int head[10001];
int dfn[10001],low[10001],q[10001];
int scc,h[10001],belong[10001],hav[10001];
bool vis[10001],inq[10001];
void dfs(int x)
{
int now;
vis[x]=inq[x]=1;
low[x]=dfn[x]=++cnt;
q[++top]=x;
int c=head[x];
while(c){
if(!vis[e[c].to]){
dfs(e[c].to);
low[x]=min(low[x],low[e[c].to]);
}else if(inq[e[c].to])low[x]=min(low[x],dfn[e[c].to]);
c=e[c].next;
}
if(low[x]==dfn[x]){
scc++;
while(now!=x){
now=q[top--];
inq[now]=0;
belong[now]=scc;
++hav[scc];
}
}
}
void rebuild()
{
cnt=0;
for(int i=1;i<=n;i++){
int c=head[i];
while(c){
if(belong[i]!=belong[e[c].to]){
d[++cnt].to=belong[e[c].to];
d[cnt].next=h[belong[i]];
h[belong[i]]=cnt;
}
c=e[c].next;
}
}
}
void tarjan()
{
for(int i=1;i<=n;i++)if(!vis[i])dfs(i);
rebuild();
}
void work()
{
int ans=0;
for(int i=1;i<=scc;i++)
if(hav[i]>1)ans++;
printf("%d\n",ans);
ans=-1;
for(int i=1;i<=scc;i++)
if(!h[i])
{
if(ans!=-1||hav[i]==1)
{
ans=-1;break;
}
else ans=i;
}
if(ans==-1)printf("%d\n",ans);
else for(int i=1;i<=n;i++)
{
if(belong[i]==ans)printf("%d ",i);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[i].to=y;
e[i].next=head[x];
head[x]=i;
}
tarjan();
work();
return 0;
}

8777

被折叠的 条评论
为什么被折叠?



