bzoj1015: [JSOI2008]星球大战

传送门

并查集裸题。

按照星球毁灭顺序从后向前插点,并向可行点连边。插入一个点联通块+1;连接一条边联通块-1。

PS刷水题有益于健康

/**************************************************************
    Problem: 1015
    User: zhouyuyang
    Language: Pascal
    Result: Accepted
    Time:2884 ms
    Memory:16036 kb
****************************************************************/
 
uses math;
var
  a,b,c,d,e,f,g,h:array [0..500005] of longint;
  n,m,k,i,p,x,y,pa:longint;
function get(x:longint):longint;
  begin
    if (x=f[x]) then exit(x);
    f[x]:=get(f[x]);
    exit(f[x]);
  end;
begin
  read(n,m);
  for i:=1 to m do read(a[i],b[i]);
  for i:=1 to m do begin a[i+m]:=b[i]; b[i+m]:=a[i]; end;
  m:=m*2;
  for i:=1 to m do
    begin
      c[i]:=d[a[i]];
      d[a[i]]:=i;
    end;
  read(k);
  for i:=1 to k do read(e[i]);
  for i:=0 to n do f[i]:=i;
  for i:=1 to k do g[e[i]]:=1;
  pa:=n-k;
  for i:=1 to n do
    if (g[i]=0) then begin
      p:=d[i];
      while (p<>0) do begin
        x:=get(a[p]); y:=get(b[p]);
        if (x<>y) and (g[b[p]]=0) then begin dec(pa); f[x]:=y; end;
        p:=c[p];
      end;
    end;
  for i:=k downto 1 do begin
    h[i]:=pa; inc(pa); g[e[i]]:=0; p:=d[e[i]];
    while (p<>0) do begin
      x:=get(a[p]); y:=get(b[p]);
      if (x<>y) and (g[b[p]]=0) then begin dec(pa); f[x]:=y; end;
      p:=c[p];
    end;
  end;
  writeln(pa);
  for i:=1 to k do writeln(h[i]);
end.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值