1. 程式人生 > >CodeForces - 613D:Kingdom and its Cities(虛樹+DP)

CodeForces - 613D:Kingdom and its Cities(虛樹+DP)

for pro void 染色 however == force don tac

Meanwhile, the kingdom of K is getting ready for the marriage of the King‘s daughter. However, in order not to lose face in front of the relatives, the King should first finish reforms in his kingdom. As the King can not wait for his daughter‘s marriage, reforms must be finished as soon as possible.

The kingdom currently consists of n cities. Cities are connected by n - 1 bidirectional road, such that one can get from any city to any other city. As the King had to save a lot, there is only one path between any two cities.

What is the point of the reform? The key ministries of the state should be relocated to distinct cities (we call such cities important). However, due to the fact that there is a high risk of an attack by barbarians it must be done carefully. The King has made several plans, each of which is described by a set of important cities, and now wonders what is the best plan.

Barbarians can capture some of the cities that are not important (the important ones will have enough protection for sure), after that the captured city becomes impassable. In particular, an interesting feature of the plan is the minimum number of cities that the barbarians need to capture in order to make all the important cities isolated, that is, from all important cities it would be impossible to reach any other important city.

Help the King to calculate this characteristic for each of his plan.

Input

The first line of the input contains integer n (1 ≤ n ≤ 100 000) — the number of cities in the kingdom.

Each of the next n - 1 lines contains two distinct integers ui, vi (1 ≤ ui, vi ≤ n) — the indices of the cities connected by the i-th road. It is guaranteed that you can get from any city to any other one moving only along the existing roads.

The next line contains a single integer q (1 ≤ q ≤ 100 000) — the number of King‘s plans.

Each of the next q lines looks as follows: first goes number ki — the number of important cities in the King‘s plan, (1 ≤ ki ≤ n), then follow exactly ki space-separated pairwise distinct numbers from 1 to n — the numbers of important cities in this plan.

The sum of all ki‘s does‘t exceed 100 000.

Output

For each plan print a single integer — the minimum number of cities that the barbarians need to capture, or print  - 1 if all the barbarians‘ attempts to isolate important cities will not be effective.

Examples

Input
4
1 3
2 3
4 3
4
2 1 2
3 2 3 4
3 1 2 4
4 1 2 3 4
Output
1
-1
1
-1
Input
7
1 2
2 3
3 4
1 5
5 6
5 7
1
4 2 4 6 7
Output
2

Note

In the first sample, in the first and the third King‘s plan barbarians can capture the city 3, and that will be enough. In the second and the fourth plans all their attempts will not be effective.

In the second sample the cities to capture are 3 and 5.

題意:這兩天看了不少的關於虛樹的題目,有些許收獲,然後此題算是最簡單,先寫此題。

思路:用DP或者貪心可以解決此題,但是由於每一次的復雜度都是O(N),而每一次的可用點是不多的,註意到sigma(K)<1e5,顯然需要建立虛樹,在虛樹上做DP或者貪心。

看到很多種虛樹的寫法,這個比較好記:

1,先按DFS序排序,然後得到相鄰的LCA,加入點集,去重。

2,建虛樹,維護一個棧,對於當前要加入的點,如果它不在棧頂的點的子樹內(也就是代碼裏的belong,用dfs序很方便的判斷),我們就一直退棧,然後棧頂向當前點連邊即可。(隊列裏維護的是一條從根到此點的dep遞增的DFS鏈

得到虛樹後就可以DP了:

從下向上遍歷,如果當前點是染色的點,那麽它需要和染色兒子切斷。如果不是染色的點,當染色兒子大於1時,需要去掉此點;當染色兒子等於1時,不用管。

#include<bits/stdc++.h>
const int maxn=100010;
using namespace std;
int Laxt[maxn],Next[maxn<<1],To[maxn<<1],dep[maxn],cnt;
int in[maxn],out[maxn],fa[maxn][18],times,a[maxn];
int q[maxn],col[maxn],sz[maxn],top,tot,ans;
vector<int>G[maxn]; 
void add(int u,int v){ Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; }
bool cmp(int x,int y){ return in[x]<in[y]; }
void dfs1(int u,int f)
{
    in[u]=++times; fa[u][0]=f; dep[u]=dep[f]+1;
    for(int i=Laxt[u];i;i=Next[i]) if(To[i]!=f) dfs1(To[i],u);
    out[u]=times;
}
int LCA(int u,int v)
{
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=17;i>=0;i--) if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];
    if(u==v) return u;
    for(int i=17;i>=0;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
    return fa[u][0];
}
bool belong(int x,int y){ return in[x]>=in[y]&&in[x]<=out[y]; } //判斷x是否在y的子樹裏。 
bool check()
{
    for(int i=1;i<=tot;i++) 
       if(col[fa[a[i]][0]]) return false; 
    return true;
}
void build()  //建立虛樹 
{
    top=0; for(int i=1;i<=tot;i++){
        while(top&&!belong(a[i],q[top])) top--;
        if(top) G[q[top]].push_back(a[i]);
        q[++top]=a[i];
    }
}
void dfs2(int u) //DP 
{
    int L=G[u].size(); 
    for(int i=0;i<L;i++){
        dfs2(G[u][i]);
        sz[u]+=sz[G[u][i]];
    }
    if(col[u]) ans+=sz[u],sz[u]=1;
    else if(sz[u]>1) ans++,sz[u]=0;
}
int main()
{
    int N,Q,K,u,v,i,j;
    scanf("%d",&N);
    for(i=1;i<N;i++){
        scanf("%d%d",&u,&v);
        add(u,v); add(v,u);
    }
    dfs1(1,0);
    for(i=1;i<=17;i++)
      for(j=1;j<=N;j++)
         fa[j][i]=fa[fa[j][i-1]][i-1];
    scanf("%d",&Q);
    while(Q--){
        scanf("%d",&K); tot=K;     ans=0; 
        for(i=1;i<=K;i++) scanf("%d",&a[i]),col[a[i]]=1;
        if(!check()){ puts("-1"); for(i=1;i<=K;i++) col[a[i]]=0; continue; }
        sort(a+1,a+tot+1,cmp);
        for(i=2;i<=K;i++) a[++tot]=LCA(a[i-1],a[i]);
        sort(a+1,a+tot+1,cmp);
        tot=unique(a+1,a+tot+1)-(a+1);
        build();
        dfs2(a[1]);
        printf("%d\n",ans);
        for(i=1;i<=tot;i++) col[a[i]]=sz[a[i]]=0,G[a[i]].clear();
    }
    return 0;
}

CodeForces - 613D:Kingdom and its Cities(虛樹+DP)