天天看点

HDU 5923 Prediction

G=⟨VG,EG⟩

G=⟨VG,EG⟩  with  

|VG|=n

|VG|=n and 

|EG|=m

|EG|=m, and a magic tree 

T=⟨VT,ET⟩)

T=⟨VT,ET⟩) rooted at 1, which contains m vertices. 

Each vertex of the magic tree corresponds to an edge in the original graph G and each edge occurs in the magic tree exactly once. 

Each query includes a set 

S(S⊆VT)

S(S⊆VT), and you should tell Mr. Frog the number of components in the modified graph 

G‘=(VG,E‘G)

G‘=(VG,EG‘), where 

E‘G

EG‘ is a set of edges in which every edge corresponds to a vertex v in magic tree T satisfying at least one of the following two conditions: 

∙v∈S

∙v∈S. 

∙v is an ancestor of some vertices in S. 

Note that the queries are independent, and namely one query will not influence another. 

Input

The input contains several test cases and the first line of the input data is an integer T, denoting the number of test cases. 

For each test case, the first line contains two integers n and m(

1≤n≤500,1≤m≤10000

1≤n≤500,1≤m≤10000), where n is the number of vertices and m is the number of edges. 

The second line contains m - 1 integers describing the magic tree, i-th integer represents the parent of the (i + 1)-th vertex. 

Then the following m lines describe the edges of the graph G. Each line contains two integers u and v indicating the two ends of the edge. 

The next line contains only one integer q(

1≤q≤50000

1≤q≤50000), indicating the number of queries. 

Then the following q lines represent queries,  i-th line represents the i-th query, which contains an integer 

ki

ki followed by 

ki

ki integers representing the set 

Si

Si.

It is guarenteed that 

∑qi=1ki≤300000

∑i=1qki≤300000.

Output

For each case, print a line "Case #x:", where x is the case number (starting from 1). 

For each query, output a single line containing only one integer representing the answer, namely the number of components. 

Sample Input

1

5 4

1 1 3

1 2

2 3

3 4

4 5

3

1 2

2 2 3

2 2 4

Sample Output

Case #1:
3
2
1      

Hint

magic tree and the original graph in the sample are:

In the first query, S = {2} and the modified graph G' = {{1, 2, 3, 4}, {(1, 2), (2, 3)}}, thus the number of the components in the modified graph is 3.

In the second query, S = {1, 2, 3}, where 1 is the ancestor of 2 (and 3) in the magic tree, and the modified graph G'' = {{1, 2, 3,4}, {(1, 2), (2, 3), (3, 4)}},

therefore the number of the components in the modified graph is 2.

In the third query, S = {1, 2, 3, 4}, where 1 is the ancestor of 2 (and 4), 3 is the ancestor of 4, and the modified graph G' = {{1, 2, 3,4}, {(1, 2), (2, 3), (3,4), (4, 5)}},

therefore the answer equals to 1.

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int> pii;
const int N = 2e4 + 10;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int low(int x) { return x&-x; }
int T, n, m, x, y,t;
int ft[N], nt[N], u[N], sz;
int a[N], b[N];
int fa[10005][505];

int get(int x,int y) {
  return y==fa[x][y]?y:fa[x][y] = get(x, fa[x][y]);
}

void dfs(int x,int y) {
  for (int i = 1;i<=n;i++) {
    fa[x][i] = fa[y][i];
  }
  int fx = get(x, a[x]);
  int fy = get(x, b[x]);
  if (fx != fy) {
    if (fx < fy) swap(fx,fy);
    fa[x][fx] = fy;
  }
  for (int i = ft[x];~i;i=nt[i]) {
    dfs(u[i], x);
  }
}

int main(){
  int cas = 1;
  for (scanf("%d",&T);T--;cas++) {
    scanf("%d%d",&n,&m);
    for (int i = 1;i<=m;i++) ft[i] = -1;
    sz = 0;
    for (int i = 2;i<=m;i++) {
      scanf("%d",&x);
      u[sz] = i; nt[sz] = ft[x]; ft[x] = sz++;
    }
    for (int i = 1;i<=m;i++) {
      scanf("%d%d",&a[i], &b[i]);
    }
    for (int i = 1;i<=n;i++) fa[0][i] = i;
    dfs(1,0);
    scanf("%d",&t);
    printf("Case #%d:\n",cas);
    while (t--) {
      scanf("%d",&x);
      for (int i = 1;i<=n;i++) fa[0][i]=i;
      int ans = n;
      while (x--) {
        scanf("%d",&y);
        for (int i = 1;i<=n;i++) {
          if (ans == 1) break;
          int fx = get(0,i);
          int fy = get(y,i);
          int fz = get(0,fy);
          if (fx == fz) continue;
          if (fx < fz) swap(fx,fz);
          fa[0][fx] = fz;
          ans--;
        }
      }
      printf("%d\n",ans);
    }
  }
  return 0;
}