2597团伙{并查集}

var
  n,m,i,x,y,j,ans:longint;
  f:array[1..1000] of longint;
  e:array[1..1000,0..1000] of longint;
  used:array[1..1000] of boolean;
  s:char;
function findset(x:longint):longint;
begin
  if x<>f[x]then
   f[x]:=findset(f[x]);
  exit(f[x]);
end;
procedure union(x,y:longint);
var
  fx,fy:longint;
begin
  fx:=findset(x);
  fy:=findset(y);
  f[fx]:=fy;
end;
function query(x,y:longint):boolean;
begin
  iffindset(x)<>findset(y) thenexit(false);
  exit(true);
end;
begin
  read(n);
  readln(m);
  for i:=1 to n do
   f[i]:=i;
  fillchar(e,sizeof(e),0);
  for i:=1 to m do
    begin
     read(s);
     readln(x,y);
      cases of
       'E':begin
            inc(e[x,0]);
            e[x,e[x,0]]:=y;
            for j:=1 to e[x,0] do
              begin
                if notquery(y,e[x,j]) then
                 union(y,e[x,j]);
              end;
            inc(e[y,0]);
            e[y,e[y,0]]:=x;
            for j:=1 to e[y,0] do
              begin
                if notquery(x,e[y,j]) then
                 union(x,e[y,j]);
              end;
           end;
       'F':union(x,y);
     end;
    end;
  ans:=0;
  fillchar(used,sizeof(used),false);
  for i:=1 to n do
    if not used[findset(i)]then
     begin
       used[findset(i)]:=true;
       inc(ans);
     end;
  writeln(ans);
end.


其实每个人的敌人只要存一个就够了,改进后,用时变为了五分之一:
var
  n,m,i,x,y,ans:longint;
  f:array[1..1000] of longint;
  e:array[1..1000] of longint;
  used:array[1..1000] of boolean;
  s:char;
function findset(x:longint):longint;
begin
  if x<>f[x]then
   f[x]:=findset(f[x]);
  exit(f[x]);
end;
procedure union(x,y:longint);
var
  fx,fy:longint;
begin
  fx:=findset(x);
  fy:=findset(y);
  f[fx]:=fy;
end;
function query(x,y:longint):boolean;
begin
  iffindset(x)<>findset(y) thenexit(false);
  exit(true);
end;
begin
  read(n);
  readln(m);
  for i:=1 to n do
   f[i]:=i;
  fillchar(e,sizeof(e),0);
  for i:=1 to m do
    begin
     read(s);
     readln(x,y);
      cases of
       'E':begin
            if (e[x]<>0) and(not query(y,e[x])) then
              union(y,e[x]);
            e[x]:=y;{更新敌人}
            if (e[y]<>0) and(not query(x,e[y])) then
              union(x,e[y]);
            e[y]:=x;
           end;
       'F':union(x,y);
     end;
    end;
  ans:=0;
  fillchar(used,sizeof(used),false);
  for i:=1 to n do
    if not used[findset(i)]then
     begin
       used[findset(i)]:=true;
       inc(ans);
     end;
  writeln(ans);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值