codevs 2822 爱在心中
题目描述 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
数据范围及提示 Data Size & Hint
各个测试点1s
爱在心中(强连通分量) /* Tarjan 求环缩点 第一问即环中点的个数大于1的环的个数 第二问 缩点后记录环的出度 统计出度为1且点的个数大于1的环的个数 若个数等于1,把出度为1的环中的点从小到大输出即可 若不等于1,则没有符合题意的 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 10010 #define maxx 1010 using namespace std; int n,m,topt,num,first[maxn],dfn[maxn],low[maxn],f[maxn],s[maxn],top,belong[maxn],du[maxn]; struct edge { int from; int to; int next; }e[maxn*2]; struct dian { int l; int a[maxx]; }p[maxx]; void add(int x,int y) { topt++; e[topt].from=x; e[topt].to=y; e[topt].next=first[x]; first[x]=topt; } void tarjan(int x) { dfn[x]=low[x]=++topt; s[++top]=x; f[x]=1; for(int i=first[x];i;i=e[i].next) { if(!dfn[e[i].to]) { tarjan(e[i].to); low[x]=min(low[x],low[e[i].to]); } else if(f[e[i].to]) low[x]=min(low[x],dfn[e[i].to]); } if(dfn[x]==low[x]) { num++; while(x!=s[top]) { p[num].l++; p[num].a[p[num].l]=s[top]; belong[s[top]]=num; f[s[top]]=0; top--; } p[num].l++; p[num].a[p[num].l]=s[top]; belong[s[top]]=num; f[s[top]]=0; top--; } } int main() { int i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=m;i++) { int x,y,z; scanf("%d%d",&x,&y); add(x,y); } for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i); int ans=0; for(i=1;i<=num;i++) if(p[i].l>1) ans++; printf("%d\n",ans); for(i=1;i<=n;i++) { for(j=first[i];j;j=e[j].next) { int f=e[j].from,t=e[j].to; if(belong[f]!=belong[t]) du[belong[f]]++; } } int sum=0; for(i=1;i<=num;i++) { if(p[i].l>1&&du[i]==0) { sum++; k=i; } } if(sum!=1) { printf("-1\n"); return 0; } int b[maxx]; for(i=1;i<=p[k].l;i++) b[i]=p[k].a[i]; sort(b+1,b+p[k].l+1); for(i=1;i<=p[k].l;i++) printf("%d ",b[i]); return 0; }