Bzoj 1015 [jsoi2008]starwar

题目大意:求删去图上一些点后,剩下的连通块有多少个。

解:自己终于开始有想法了,就是离线算法,把询问记录,全部删去后在反过来加上去,用并查集维护分量的根,囧死人的是不知道为什么用dfs求连通分量会wa,用并查集就ac了,而且运行时间真的有点慢了..对拍下看看哪里错了..

View Code
  1 const
  2         inf='1.txt';
  3         maxm=211111;
  4         maxn=maxm << 1;
  5 type
  6         type_edge=record
  7           dest, next, op: longint;
  8         end;
  9 var
 10         edge: array[0..maxm*2]of type_edge;
 11         iq, visit: array[0..maxn]of boolean;
 12         stack, ans, vect, fa, ask: array[0..maxn]of longint;
 13         l, r: array[0..maxm]of longint;
 14         stacktot, ltk, n, m, q, anstot, tot: longint;
 15 procedure add(x, y: longint);
 16 begin
 17   inc(tot);
 18   with edge[tot] do begin
 19     dest := y;
 20     next := vect[x];
 21     vect[x] := tot;
 22     op := tot + 1;
 23   end;
 24   inc(tot);
 25   with edge[tot] do begin
 26     dest := x;
 27     next := vect[y];
 28     vect[y] := tot;
 29     op := tot - 1;
 30   end;
 31 end;
 32 
 33 procedure search(x, father: longint);
 34 var
 35         u, i: longint;
 36 begin
 37   inc(stacktot); stack[stacktot] := x; iq[x] := true;
 38   repeat
 39     u := stack[stacktot]; dec(stacktot);
 40     visit[u] := true;
 41     i := vect[u];
 42     while i<>0 do
 43       with edge[i] do begin
 44         if (not visit[dest])and(not iq[dest]) then begin
 45           inc(stacktot); stack[stacktot] := dest;
 46         end;
 47         i := next;
 48       end;
 49   until stacktot=0;
 50 end;
 51 
 52 function find(x: longint): longint;
 53 begin
 54   if fa[x]=x then exit(x);
 55   fa[x] := find(fa[x]);
 56   exit(fa[x]);
 57 end;
 58 
 59 procedure init;
 60 var
 61         i, x, y: longint;
 62 begin
 63   anstot := 0; tot := 0; ltk := 0;
 64   fillchar(vect, sizeof(vect), 0);
 65   readln(n, m);
 66   dec(n);
 67   for i := 1 to m do begin
 68     readln(x, y);
 69     add(x, y);
 70     l[i] := x; r[i] := y;
 71   end;
 72 
 73   fillchar(visit, sizeof(visit), 0);
 74   fillchar(iq, sizeof(iq), 0);
 75   for i := 0 to n do fa[i] := i;
 76   readln(q);
 77   for i := 1 to q do readln(ask[i]);
 78   for i := 1 to q do visit[ask[i]] := true;
 79   for i := 0 to n do
 80     if not visit[i] then begin
 81       inc(ltk);
 82       stacktot := 0;
 83       search(i, i);
 84     end;
 85   fillchar(visit, sizeof(visit), 0);
 86   for i := 1 to q do visit[ask[i]] := true;{
 87   ltk := n+1 - q;
 88   for i := 1 to m do
 89     if (not(visit[l[i]]))and(not(visit[r[i]])) then begin
 90       x := find(l[i]); y := find(r[i]);
 91       if x<>y then begin
 92         dec(ltk);
 93         fa[y] := fa[x];
 94       end;
 95     end; }
 96 end;
 97 
 98 
 99 procedure push(x: longint);
100 var
101         a, b, i: longint;
102 begin
103   visit[x] := false; a := fa[x];
104   i := vect[x];
105   while i<>0 do
106     with edge[i] do begin
107       if (not visit[dest])and(dest<>x) then begin
108         a := find(dest);
109         i := next; break;
110       end;
111       i := next;
112     end;
113   if a = fa[x] then inc(ltk);
114   fa[x] := a;
115   while i<>0 do
116     with edge[i] do begin
117       if (not visit[dest])and(dest<>x) then begin
118         b := find(dest);
119         if a<>b then begin
120           dec(ltk);
121           fa[b] := fa[a];
122         end;
123       end;
124       i := next;
125     end;
126 end;
127 
128 procedure main;
129 begin
130   while (q>0) do begin
131     inc(anstot); ans[anstot] := ltk;
132     push(ask[q]);
133     dec(q);
134   end;
135   inc(anstot); ans[anstot] := ltk;
136 end;
137 
138 procedure print;
139 var
140         i: longint;
141 begin
142   for i :=anstot downto 1 do writeln(ans[i]);
143 end;
144 
145 begin
146   assign(input,inf); reset(input);
147   init;
148   main;
149   print;
150 end.

 

 

posted @ 2012-04-13 13:27  F.D.His.D  阅读(193)  评论(0编辑  收藏  举报