vijos p1022题解

原题叙述

这题又是舞会...这题继续搞笑....

牛人们说这是强联通分量,很标准;但是我写了个并查集,沙茶的通过了。

强联通分量很明显,不说了。我说说我的并查集:

因为每组任何一个成员都能在这组中找到自己想聊天的对象,于是将他们设想成点。

即,若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]=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<>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..200of 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.
原文地址:https://www.cnblogs.com/waterfalleagle/p/1595642.html