bzoj 1015 并查集

逆向思维,先将整张图以最后所有要求的点毁掉的状态建图,然后倒着

加点就行了,用并查集维护连通块

/**************************************************************
    Problem: 1015
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:2588 ms
    Memory:16340 kb
****************************************************************/
 
//By BLADEVIL
var
    n, m, k                     :longint;
    flag                        :array[0..500010] of boolean;
    pre, other, last            :array[0..500010] of longint;
    delete, x, y, ans           :array[0..500010] of longint;
    father                      :array[0..500010] of longint;
    l                           :longint;
     
     
procedure connect(x,y:longint);
begin
    inc(l);
    pre[l]:=last[x];
    last[x]:=l;
    other[l]:=y;
end;
 
procedure init;
var
    i                           :longint;
begin
    read(n,m);
    for i:=1 to m do
    begin
        read(x[i],y[i]);
        connect(x[i],y[i]);
        connect(y[i],x[i]);
    end;
    read(k);
    for i:=1 to k do
    begin
        read(delete[i]);
        flag[delete[i]]:=true;
    end;
end;
 
function getfather(x:longint):longint;
begin
    if father[x]=x then exit(x);
    father[x]:=getfather(father[x]);
    exit(father[x]);
end;
 
procedure main;
var
    i                           :longint;
    fa, fb                      :longint;
    cur                         :longint;
    q, p                        :longint;
     
begin
    for i:=0 to n-1 do father[i]:=i; 
    for i:=1 to m do
    begin
        if (not flag[x[i]]) and (not flag[y[i]]) then
        begin
            fa:=getfather(x[i]); fb:=getfather(y[i]);
            if fa<>fb then father[fa]:=fb;
        end;
    end;
    for i:=0 to n do if (not flag[i]) and (father[i]=i) then inc(ans[k+1]); 
    for i:=k downto 1 do
    begin
        cur:=delete[i];
        ans[i]:=ans[i+1];
        q:=last[cur];
        inc(ans[i]);
        while q<>0 do
        begin
            p:=other[q];
            if not flag[p] then
            begin  
                fa:=getfather(p);
                if fa<>cur then
                begin
                    dec(ans[i]);
                    father[fa]:=cur;
                end;
            end;
            q:=pre[q];
        end;
        flag[cur]:=false;
    end;
    for i:=1 to k+1 do writeln(ans[i]);
end;
 
 
begin
    init;
    main;
end.

 

posted on 2013-12-29 01:25  BLADEVIL  阅读(390)  评论(0编辑  收藏  举报