这题又是舞会...这题继续搞笑....
牛人们说这是强联通分量,很标准;但是我写了个并查集,沙茶的通过了。
强联通分量很明显,不说了。我说说我的并查集:
因为每组任何一个成员都能在这组中找到自己想聊天的对象,于是将他们设想成点。
即,若b在一个集合V,a不在,而点a与b有联系,将a并入集合V中,且因为要让分组数最小,所以a想交流的所有点都并入集合V中。如果(写到这,发现这题错了.....我说是题目叙述与数据完全两码事!我倒....不写了)
我的代码:
var i,n,ch,t,s,m:longint;a:array[1..200]of longint;
v:array[1..200]of boolean;
function find(x:longint):longint;
begin
if a[x]=x then a[x]:=x
else
a[x]:=find(a[x]);
find:=a[x];
end;
begin
readln(n);
for i:=1 to n do a[i]:=i;
for i:=1 to n do
begin
read(ch);
while ch<>0 do
begin
if a[i]<>a[ch] then
begin
t:=find(i);s:=find(ch);
if t<>s then a[s]:=t;
end;
read(ch);
end;
readln;
end;
fillchar(v,sizeof(v),0);
m:=0;
for i:=1 to n do t:=find(i);
for i:=1 to n do
if not(v[a[i]]) then
begin
inc(m);
v[a[i]]:=true;
end;
writeln(m);
end.
v:array[1..200]of boolean;
function find(x:longint):longint;
begin
if a[x]=x then a[x]:=x
else
a[x]:=find(a[x]);
find:=a[x];
end;
begin
readln(n);
for i:=1 to n do a[i]:=i;
for i:=1 to n do
begin
read(ch);
while ch<>0 do
begin
if a[i]<>a[ch] then
begin
t:=find(i);s:=find(ch);
if t<>s then a[s]:=t;
end;
read(ch);
end;
readln;
end;
fillchar(v,sizeof(v),0);
m:=0;
for i:=1 to n do t:=find(i);
for i:=1 to n do
if not(v[a[i]]) then
begin
inc(m);
v[a[i]]:=true;
end;
writeln(m);
end.
牛人的联通分量
FLOYD!!!
用floyed来求出某人愿意与什么人来交流,然后一个贪心过去,就是正解。
至于细节就不说了,看代码吧。。。
====================晒程序=====================
var
n,i,x,j,k,ans:longint;
f:array[0..200,0..200]of boolean;
u:array[0..200] of boolean;
begin
readln(n);
fillchar(f,sizeof(f),false);
for i:=1 to n do begin
read(x);
while x>0 do begin
f[i,x]:=true;
read(x);
end;
readln;
end;
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
begin
if (i=k)or(i=j)or(k=j)or(f[i,j]) then continue;
f[i,j]:=(f[i,k]and f[k,j]);
end;
fillchar(u,sizeof(u),0);
for i:=1 to n do
if not u[i] then
begin
inc(ans);
u[i]:=true;
for j:=1 to n do u[j]:=u[j] or f[i,j];
end;
writeln(ans);
end.
用floyed来求出某人愿意与什么人来交流,然后一个贪心过去,就是正解。
至于细节就不说了,看代码吧。。。
====================晒程序=====================
var
n,i,x,j,k,ans:longint;
f:array[0..200,0..200]of boolean;
u:array[0..200] of boolean;
begin
readln(n);
fillchar(f,sizeof(f),false);
for i:=1 to n do begin
read(x);
while x>0 do begin
f[i,x]:=true;
read(x);
end;
readln;
end;
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
begin
if (i=k)or(i=j)or(k=j)or(f[i,j]) then continue;
f[i,j]:=(f[i,k]and f[k,j]);
end;
fillchar(u,sizeof(u),0);
for i:=1 to n do
if not u[i] then
begin
inc(ans);
u[i]:=true;
for j:=1 to n do u[j]:=u[j] or f[i,j];
end;
writeln(ans);
end.