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.