【题目描述】:
“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢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
分析:
先缩点,用tarjan算法
再输出强连通分量个数(在这里强连通分量中1个以上才算强连通分量)
为了找出被所有人爱的一个集合
算出每个点的出度,出度为0的点才有可能被所有人爱
但是出度为0的点不能多于1个,如果多于一个则证明这是多棵树
也不能是一个点,因为他不是一个爱心天使
代码:
var
low,dfn,st,c,k,o,oo,k1:array [1..1000] of integer;
a:array [1..1000,1..1000] of integer;
b:array [1..1000,1..1000] of boolean;
f,v,boo:array [1..1000] of boolean;
bb:array [1..1000,1..2] of longint;
i,j,m,n,tot,x,y,d,t,ans,p:longint;
function min(x,y:longint):longint;
begin
if x>y then
exit(y);
exit(x);
end;
function pp:longint;
begin
f[st[t]]:=false;
dec(t);
exit(st[t+1]);
end;
procedure targan(x:longint);
var
i:longint;
begin
inc(d);
dfn[x]:=d;
low[x]:=d;
inc(t);
st[t]:=x;
f[x]:=true;
for i:=1 to c[x] do
begin
if not v[a[x,i]] then
begin
v[a[x,i]]:=true;
targan(a[x,i]);
low[x]:=min(low[x],low[a[x,i]]);
end else
begin
if f[a[x,i]] then
low[x]:=min(low[x],dfn[a[x,i]]);
end;
end;
if dfn[x]=low[x] then
begin
inc(p);
repeat
inc(o[p]);
y:=pp;
oo[y]:=p;
b[p,y]:=true;
until x=y;
if o[p]>1 then
inc(ans);
end;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
inc(c[x]);
inc(k1[y]);
a[x,c[x]]:=y;
bb[i,1]:=x;
bb[i,2]:=y;
end;
for i:=1 to n do
if not v[i] then
begin
v[i]:=true;
targan(i);
end;
writeln(ans);
for i:=1 to m do
begin
if (oo[bb[i,1]]<>oo[bb[i,2]]) then
boo[oo[bb[i,1]]]:=true;
end;
for i:=1 to p do
begin
if not boo[i] and (o[i]>1) then
begin
x:=i;
inc(tot);
end;
end;
if tot<>1 then
writeln('-1') else
for i:=1 to n do
if b[x,i] then
write(i,' ');
writeln;
end.
low,dfn,st,c,k,o,oo,k1:array [1..1000] of integer;
a:array [1..1000,1..1000] of integer;
b:array [1..1000,1..1000] of boolean;
f,v,boo:array [1..1000] of boolean;
bb:array [1..1000,1..2] of longint;
i,j,m,n,tot,x,y,d,t,ans,p:longint;
function min(x,y:longint):longint;
begin
if x>y then
exit(y);
exit(x);
end;
function pp:longint;
begin
f[st[t]]:=false;
dec(t);
exit(st[t+1]);
end;
procedure targan(x:longint);
var
i:longint;
begin
inc(d);
dfn[x]:=d;
low[x]:=d;
inc(t);
st[t]:=x;
f[x]:=true;
for i:=1 to c[x] do
begin
if not v[a[x,i]] then
begin
v[a[x,i]]:=true;
targan(a[x,i]);
low[x]:=min(low[x],low[a[x,i]]);
end else
begin
if f[a[x,i]] then
low[x]:=min(low[x],dfn[a[x,i]]);
end;
end;
if dfn[x]=low[x] then
begin
inc(p);
repeat
inc(o[p]);
y:=pp;
oo[y]:=p;
b[p,y]:=true;
until x=y;
if o[p]>1 then
inc(ans);
end;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
inc(c[x]);
inc(k1[y]);
a[x,c[x]]:=y;
bb[i,1]:=x;
bb[i,2]:=y;
end;
for i:=1 to n do
if not v[i] then
begin
v[i]:=true;
targan(i);
end;
writeln(ans);
for i:=1 to m do
begin
if (oo[bb[i,1]]<>oo[bb[i,2]]) then
boo[oo[bb[i,1]]]:=true;
end;
for i:=1 to p do
begin
if not boo[i] and (o[i]>1) then
begin
x:=i;
inc(tot);
end;
end;
if tot<>1 then
writeln('-1') else
for i:=1 to n do
if b[x,i] then
write(i,' ');
writeln;
end.