这题又是舞会...这题继续搞笑....
牛人们说这是强联通分量,很标准;但是我写了个并查集,沙茶的通过了。
强联通分量很明显,不说了。我说说我的并查集:
因为每组任何一个成员都能在这组中找到自己想聊天的对象,于是将他们设想成点。
即,若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 .