【codevs2822】爱在心中 tarjan 缩点+理解
【codevs2822】爱在心中
题目描述 Description
“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”
在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。
如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。
现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。
输入描述 Input Description
第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。
第2到第M+1行,每行两个数A、B,代表A爱B。
输出描述 Output Description
第1行,一个数,代表爱的国度里有多少爱心天使。
第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。
样例输入 Sample Input
样例输入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
样例输出 Sample Output
样例输出1:
2
2 3样例输出2:
1
-1
代码
#include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <queue> #include <typeinfo> #include <map> #include<bits/stdc++.h> typedef long long ll; using namespace std; #define inf 10000000 inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } //*************************************************************** struct ss { int u,to,next; } e[50001]; int out[40001]; int head[50001],vis[50001],dfn[50001],low[50001],belong[50001],hav[50001]; int q[50001],inq[50001]; int t=1,bcnt,cnt,n,m,top; void add(int u,int v) { e[t].to=v; e[t].u=u; e[t].next=head[u]; head[u]=t++; } void dfs(int u) { vis[u]=inq[u]=1; low[u]=dfn[u]=++cnt; q[++top]=u; for(int i=head[u]; i; i=e[i].next) { if(!vis[e[i].to]) { dfs(e[i].to); low[u]=min(low[u],low[e[i].to]); } else if(inq[e[i].to])low[u]=min(low[u],dfn[e[i].to]); } int v=-1; if(low[u]==dfn[u]) { bcnt++; while(v!=u) { v=q[top--]; inq[v]=0; belong[v]=bcnt; hav[bcnt]++; } } } void rebuild() { for(int i=1; i<=m; i++) { if(belong[e[i].u]!=belong[e[i].to]) { out[belong[e[i].u]]++; } } } void tarjan() { for(int i=1; i<=n; i++) { if(!vis[i]) { dfs(i); } } rebuild(); } void work() { int res=0; int ans; for(int i=1; i<=bcnt; i++) { if(out[i]==0) { ans=i; res++; } } int bb=0; for(int i=1;i<=bcnt;i++) { if(hav[i]>=2)bb++; } cout<<bb<<endl; if(res==1) { if(hav[ans]!=1) { int kk=0; int hh[50001]; for(int i=1; i<=n; i++) { if(belong[i]==ans) { hh[++kk]=i; } } for(int i=1; i<kk; i++) { printf("%d ",hh[i]); } cout<<hh[kk]<<endl; } else cout<<-1<<endl; } else cout<<-1<<endl; } int main() { int u,v; scanf("%d%d",&n,&m); for(int i=1; i<=m; i++) { scanf("%d%d",&u,&v); add(u,v); } tarjan(); work(); return 0; }