【CodeVS】2822 爱在心中 [2017年6月计划 强连通分量03]

2822 爱在心中

 

时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
 
 
 
 
题目描述 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

 

 

 一个人不算天使,模板题稍微修改一下即可过

良心样例

#include <bits/stdc++.h>
inline int max(int a, int b){return a < b ? b : a;}
inline int min(int a, int b){return a < b ? a : b;}
inline void read(int &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')x = -x;}
inline void read(long long &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')x = -x;}
const int INF = 0x3f3f3f3f;
const int MAXN = 100000 + 10;
const int MAXM = 100000 + 10;
struct Edge
{
	int u,v,next;
}edge1[MAXM];
int head1[MAXM],cnt1;
inline void insert1(int a, int b){edge1[++cnt1] = Edge{a, b, head1[a]};head1[a] = cnt1;}

Edge edge2[MAXM];
int head2[MAXN],cnt2;
inline void insert2(int a, int b){edge2[++cnt2] = Edge{a, b, head2[a]};head2[a] = cnt2;}

int n,m;

int stack[MAXN],top,t,group,belong[MAXN],dfn[MAXN],low[MAXN],num[MAXN];
bool b[MAXN], bb[MAXN];

int tmp1, tmp2;

int ans, ansgroup;

void dfs(int u)
{
	dfn[u] = low[u] = ++t;
	b[u] = bb[u] = true;
	stack[++top] = u;
	for(int pos = head1[u];pos;pos = edge1[pos].next)
	{
		int v = edge1[pos].v;
		if(!b[v])
		{
			dfs(v);
			low[u] = min(low[v], low[u]);
		}
		else if(bb[v] && low[u] > dfn[v])
		{
			low[u] = dfn[v];
		}
	}
	
	if(low[u] == dfn[u])
	{
		group ++;
		int now = 0;
		while(now != u)
		{
			now = stack[top--];
			belong[now] = group;
			bb[now] = false;
			num[group] ++;
		}
		if(num[group] > 1)ansgroup ++;
	}
} 

inline void rebuild()
{
	for(int u = 1;u <= n;u ++)
	{
		for(int pos = head1[u];pos;pos = edge1[pos].next)
		{
			int v = edge1[pos].v;
			if(belong[u] != belong[v])
			{
				insert2(belong[u], belong[v]);
			}
		}
	}
}

inline void tarjan()
{
	for(int i = 1;i <= n;i ++)if(!b[i])dfs(i);
	rebuild();
}

int main()
{
	read(n);read(m);
	for(int i = 1;i <= m;i ++)
	{
		read(tmp1);read(tmp2);
		insert1(tmp1, tmp2);
	}
	tarjan();
	printf("%d\n", ansgroup);
	for(int i = 1;i <= group;i ++)
	{
		if(!head2[i])
		{
			if(ans)
			{
				ans = 0;break;
			}
			else if(num[i] != 1)
			{
				ans = i;
			}
		}
	}
	if(ans == 0)
	{
		printf("-1");
		return 0;
	}
	for(int i = 1;i <= n;i ++)
	{
		if(belong[i] == ans)
		{
			printf("%d ", i);
		}
	}
	return 0;
} 

 

posted @ 2017-06-20 17:30  嘒彼小星  阅读(204)  评论(0编辑  收藏  举报