1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int N = 3005, M = 6005; #define con(typ) const typ &
template<const int P, const int E> struct Graph { int head[P], to[E], nxt[E], ncnt; void addEdge(con(int) u, con(int) v) { int p = ++ncnt; to[p] = v, nxt[p] = head[u]; head[u] = p; } inline int operator [] (con(int) u) const {return head[u];} }; Graph<N, M> gr, rg; Graph<N, N> tre;
int n, m, nq, ndfn; bool dom[N][N], rea[N][N]; int tag[N], que[N], deg[N], fa[N], ans[N], siz[N], dfn[N];
inline int rin(int &r) { int c = getchar(); r = 0; while ( c < '0' || '9' < c ) c = getchar(); while ( '0' <= c && c <= '9' ) r = (r * 10) + (c ^ '0'), c = getchar(); return r; } inline void write(con(int) w) { if ( w < 10 ) putchar(w ^ '0'); else write(w / 10), putchar((w % 10) ^ '0'); } void bfs(con(int) ban) { int ql = 1, qr = 1; que[1] = 1, tag[1] = ban; while ( ql <= qr ) { int u = que[ql++]; for (int it = gr[u]; it; it = gr.nxt[it]) { int v = gr.to[it]; if ( v != ban && tag[v] != ban ) que[++qr] = v, tag[v] = ban; } } for (int i = 1; i <= n; i++) if ( tag[i] != ban ) deg[i]++, dom[ban][i] = true; } void build() { int ql = 1, qr = 1; que[1] = 1; while ( ql <= qr ) { int u = que[ql++]; for (int v = 1; v <= n; v++) if ( dom[u][v] && (--deg[v]) == 1 ) { fa[v] = u, que[++qr] = v; tre.addEdge(u, v); } } } void dfs(con(int) u) { dfn[u] = ++ndfn, siz[u] = 1; for (int it = tre[u]; it; it = tre.nxt[it]) dfs(tre.to[it]), siz[u] += siz[tre.to[it]]; } void getReach(con(int) s, con(int) ban) { int ql = 1, qr = 1; que[1] = s; rea[s][s] = true; while ( ql <= qr ) { int u = que[ql++]; for (int it = rg[u]; it; it = rg.nxt[it]) { int v = rg.to[it]; if ( v != ban && !rea[s][v] ) rea[s][v] = true, que[++qr] = v; } } } int main() {
rin(n), rin(m), rin(nq); for (int i = 1, u, v; i <= m; i++) { rin(u), rin(v); gr.addEdge(u, v), rg.addEdge(v, u); } for (int i = 1; i <= n; i++) deg[i]++, dom[1][i] = true; for (int i = 2; i <= n; i++) bfs(i); build(), dfs(1); for (int i = 2; i <= n; i++) getReach(i, fa[i]); while ( nq-- ) { int s, t; rin(s), rin(t); for (int i = 2; i <= n; i++) if ( !dom[fa[i]][s] && rea[i][t] ) ans[dfn[i]]++, ans[dfn[i] + siz[i]]--; int tot = 0; for (int i = 1; i <= n + 1; i++) { ans[i] += ans[i - 1]; if ( ans[i] ) tot++; ans[i - 1] = 0; } write(tot), putchar('\n'); } return 0; }
|