zoukankan      html  css  js  c++  java
  • CF613D Kingdom and its Cities(虚树)

    通过领悟题意,发现本题只与关键点和他们的lca有关,因此把只需要对他们建虚树

    对于dp思路,如果x不是关键点,那么观察子树中有多少需要断开的,如果超过1,那么直接断开这个点,如果等于1,先保留看看能否与后面的一起。

    如果是关键点,那就必须要把当前点和子树中的所有关键点断开,首先我们知道一定存在合法方案,因为不存在的已经特判过了,所以只需记录子树中的个数即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e5+10;
    const int mod=998244353;
    vector<int> g1[N],g[N];
    int dfn[N],times,f[N][25],st[N],depth[N];
    int cnt[N],q[N],d[N],sign[N];
    int vis[N];
    void dfs(int u,int fa){
        depth[u]=depth[fa]+1;
        dfn[u]=++times;
        int i;
        f[u][0]=fa;
        for(i=1;i<=21;i++){
            f[u][i]=f[f[u][i-1]][i-1];
        }
        for(i=0;i<g1[u].size();i++){
            int v=g1[u][i];
            if(v==fa)
                continue;
            dfs(v,u);
        }
    }
    bool cmp(int x,int y){
        return dfn[x]<dfn[y];
    }
    int lca(int a,int b){
        if(depth[a]<depth[b])
            swap(a,b);
        int i;
        for(i=21;i>=0;i--){
            if(depth[f[a][i]]>=depth[b]){
                a=f[a][i];
            }
        }
        if(a==b)
            return a;
        for(i=21;i>=0;i--){
            if(f[a][i]!=f[b][i]){
                a=f[a][i];
                b=f[b][i];
            }
        }
        return f[a][0];
    }
    void add(int a,int b){
        g[a].push_back(b);
    }
    void get(int u){
        int i;
        int cnt=0;
        for(i=0;i<g[u].size();i++){
            int v=g[u][i];
            get(v);
            d[u]+=d[v];
            if(st[u]){
                d[u]+=sign[v];
            }
            else{
                if(sign[v])
                    cnt++;
            }
            d[v]=0,st[v]=0,sign[v]=0,vis[v]=0;
        }
        if(!st[u]){
            if(cnt>1){
                d[u]++;
            }
            else if(cnt==1){
                sign[u]=1;
            }
        }
        g[u].clear();
    }
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        for(i=1;i<n;i++){
            int a,b;
            cin>>a>>b;
            g1[a].push_back(b);
            g1[b].push_back(a);
        }
        dfs(1,0);
        int t;
        cin>>t;
        while(t--){
            int k;
            cin>>k;
            for(i=1;i<=k;i++){
                int x;
                cin>>x;
                st[x]=1;
                cnt[i]=x;
                sign[x]=1;
                vis[x]=1;
            }
            int kk=0;
            for(i=1;i<=k;i++){
                if(vis[f[cnt[i]][0]]){
                    kk=1;
                    break;
                }
            }
            if(kk){
                for(i=1;i<=k;i++){
                    vis[cnt[i]]=0;
                    sign[cnt[i]]=0;
                    st[cnt[i]]=0;
                }
                cout<<-1<<endl;
                continue;
            }
            sort(cnt+1,cnt+1+k,cmp);
            q[1]=1;
            int tt=1;
            for(i=1;i<=k;i++){
                if(cnt[i]==1)
                    continue;
                int p=lca(cnt[i],q[tt]);
                if(p!=q[tt]){
                    while(dfn[p]<dfn[q[tt-1]]){
                        add(q[tt-1],q[tt]);
                        tt--;
                    }
                    if(dfn[p]!=dfn[q[tt-1]]){
                        add(p,q[tt]);
                        q[tt]=p;
                    }
                    else{
                        add(p,q[tt]);
                        tt--;
                    }
                }
                q[++tt]=cnt[i];
            }
            for(i=1;i<tt;i++){
                add(q[i],q[i+1]);
            }
            get(1);
            cout<<d[1]<<endl;
            d[1]=0,sign[1]=0,st[1]=0,vis[1]=0;
        }
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    LIS(nlogn) POJ 3903 Stock Exchange
    LCS(滚动数组) POJ 1159 Palindrome
    LCS(打印全路径) POJ 2264 Advanced Fruits
    3-16 提取任务(第6章)
    3-15 《元编程》第6章 3-16 hook method
    3-13《元编程》第5章Class Definitions 3-14(5-4Singleton Classes,2小时)3-15(3小时✅)
    3-11 《Ruby元编程》第4章block块 3-12
    3-9《元编程》第3章Tuesday:methods
    3-8《Ruby元编程》第二章对象模型
    2-27 最短路径《啊哈算法》2-28完成四种算法
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13362950.html
Copyright © 2011-2022 走看看