CF613D Kingdom and its Cities

题目链接

问题分析

首先看数据范围不难发现是虚树。

但是这个DP怎么写的我这么难受……

应该是不难的DP,\(F[i][0]\)表示\(i\)不占领,\(F[i][1]\)表示\(i\)占领,然后分类讨论……具体的见代码吧……

参考程序

#include <bits/stdc++.h>
using namespace std;

const int Maxn = 100010;
const int INF = 1000010;
const int MaxLog = 20;
struct edge {
    int Next, To;
    edge() {}
    edge( int _To, int _Next ) : Next( _Next ), To( _To ) {}
};
struct graph {
    int Start[ Maxn ], Used;
    edge Edge[ Maxn << 1 ];
    int State, Flag[ Maxn ], Important[ Maxn ];
    graph() {
        memset( Flag, 255, sizeof( Flag ) );
        memset( Important, 255, sizeof( Important ) );
        Used = State = 0;
        return;
    }
    inline void Set( int _State ) {
        State = _State; Used = 0;
        return;
    }
    inline void SetImportant( int u ) {
        Important[ u ] = State;
        return;
    }
    inline bool IsImportant( int u ) {
        return Important[ u ] == State;
    }
    inline void AddDirectedEdge( int x, int y ) {
        if( Flag[ x ] != State ) {
            Flag[ x ] = State;
            Start[ x ] = 0;
        }
        Edge[ ++Used ] = edge( y, Start[ x ] );
        Start[ x ] = Used;
        return;
    }
    inline void AddUndirectedEdge( int x, int y ) {
        AddDirectedEdge( x, y );
        AddDirectedEdge( y, x );
        return;
    }
};
graph Prime, Now;
int n, q, k, A[ Maxn ];
int Deep[ Maxn ], D[ Maxn ][ MaxLog ], Dfn[ Maxn ], Time;

void Build( int u, int Fa ) {
    Dfn[ u ] = ++Time;
    Deep[ u ] = Deep[ Fa ] + 1;
    D[ u ][ 0 ] = Fa;
    for( int i = 1; i < MaxLog; ++i )
        D[ u ][ i ] = D[ D[ u ][ i - 1 ] ][ i - 1 ];
    for( int t = Prime.Start[ u ]; t; t = Prime.Edge[ t ].Next ) {
        int v = Prime.Edge[ t ].To;
        if( v == Fa ) continue;
        Build( v, u );
    }
    return;
}

int GetLca( int x, int y ) {
    if( Deep[ x ] < Deep[ y ] ) swap( x, y );
    for( int i = MaxLog - 1; i >= 0; --i )
        if( Deep[ D[ x ][ i ] ] >= Deep[ y ] )
            x = D[ x ][ i ];
    if( x == y ) return x;
    for( int i = MaxLog - 1; i >= 0; --i )
        if( D[ x ][ i ] != D[ y ][ i ] ) {
            x = D[ x ][ i ];
            y = D[ y ][ i ];
        }
    return D[ x ][ 0 ];
}

int Stack[ Maxn ];

bool Cmp( int x, int y ) {
    return Dfn[ x ] < Dfn[ y ];
}

int F[ Maxn ][ 2 ];

void Dp( int u, int Fa ) {
    for( int t = Now.Start[ u ]; t; t = Now.Edge[ t ].Next ) {
        int v = Now.Edge[ t ].To;
        if( v == Fa ) continue;
        Dp( v, u );
    }
    if( Now.IsImportant( u ) ) {
        F[ u ][ 0 ] = INF;
        F[ u ][ 1 ] = 0;
        for( int t = Now.Start[ u ]; t; t = Now.Edge[ t ].Next ) {
            int v = Now.Edge[ t ].To;
            if( v == Fa ) continue;
            if( Deep[ v ] - Deep[ u ] > 1 )
                F[ u ][ 1 ] += min( F[ v ][ 0 ], F[ v ][ 1 ] + 1 );
            else
                F[ u ][ 1 ] += F[ v ][ 0 ];
        }
    } else {
        F[ u ][ 0 ] = 0;
        int Max = 0;
        for( int t = Now.Start[ u ]; t; t = Now.Edge[ t ].Next ) {
            int v = Now.Edge[ t ].To;
            if( v == Fa ) continue;
            if( Deep[ v ] - Deep[ u ] > 1 ) {
                F[ u ][ 0 ] += min( F[ v ][ 0 ], F[ v ][ 1 ] + 1 );
                Max = max( Max, min( F[ v ][ 0 ], F[ v ][ 1 ] + 1 ) - F[ v ][ 1 ] );
            } else {
                F[ u ][ 0 ] += F[ v ][ 0 ];
                Max = max( Max, F[ v ][ 0 ] - F[ v ][ 1 ] );
            }
        }
        F[ u ][ 1 ] = F[ u ][ 0 ] - Max;
        int T = 1;
        for( int t = Now.Start[ u ]; t; t = Now.Edge[ t ].Next ) {
            int v = Now.Edge[ t ].To;
            if( v == Fa ) continue;
            T += min( F[ v ][ 0 ], F[ v ][ 1 ] );
        }
        F[ u ][ 0 ] = min( F[ u ][ 0 ], T );
    }
    return;
}

int main() {
    Prime.Set( 0 );
    scanf( "%d", &n );
    for( int i = 1; i < n; ++i ) {
        int x, y;
        scanf( "%d%d", &x, &y );
        Prime.AddUndirectedEdge( x, y );
    }
    Build( 1, 0 );
    scanf( "%d", &q );
    for( int i = 1; i <= q; ++i ) {
        Now.Set( i );
        scanf( "%d", &k );
        for( int j = 1; j <= k; ++j ) scanf( "%d", &A[ j ] );
        for( int j = 1; j <= k; ++j ) Now.SetImportant( A[ j ] );
        sort( A + 1, A + k + 1, Cmp );
        Stack[ 0 ] = Stack[ 1 ] = 1;
        for( int j = 1; j <= k; ++j ) {
            if( j == 1 && A[ 1 ] == 1 ) continue;
            int Lca = GetLca( Stack[ Stack[ 0 ] ], A[ j ] );
            if( Deep[ Lca ] == Deep[ Stack[ Stack[ 0 ] ] ] )
                Stack[ ++Stack[ 0 ] ] = A[ j ];
            else {
                while( Deep[ Lca ] < Deep[ Stack[ Stack[ 0 ] - 1 ] ] ) {
                    Now.AddUndirectedEdge( Stack[ Stack[ 0 ] ], Stack[ Stack[ 0 ] - 1 ] );
                    --Stack[ 0 ];
                }
                if( Deep[ Lca ] == Deep[ Stack[ Stack[ 0 ] - 1 ] ] ) {
                    Now.AddUndirectedEdge( Stack[ Stack[ 0 ] ], Stack[ Stack[ 0 ] - 1 ] );
                    --Stack[ 0 ];
                    Stack[ ++Stack[ 0 ] ] = A[ j ];
                } else {
                    Now.AddUndirectedEdge( Stack[ Stack[ 0 ] ], Lca );
                    --Stack[ 0 ];
                    Stack[ ++Stack[ 0 ] ] = Lca;
                    Stack[ ++Stack[ 0 ] ] = A[ j ];
                }
            }
        }
        while( Stack[ 0 ] > 1 ) {
            Now.AddUndirectedEdge( Stack[ Stack[ 0 ] ], Stack[ Stack[ 0 ] - 1 ] );
            --Stack[ 0 ];
        }
        Dp( 1, 0 );
        int Ans = min( F[ 1 ][ 0 ], F[ 1 ][ 1 ] );
        if( Ans > n ) printf( "-1\n" ); else printf( "%d\n", Ans );
    }
    return 0;
}

原文地址:https://www.cnblogs.com/chy-2003/p/11608664.html

时间: 2024-11-01 17:07:40

CF613D Kingdom and its Cities的相关文章

CF613D Kingdom and its Cities 虚树

传送门 $\sum k \leq 100000$虚树套路题 设$f_{i,0/1}$表示处理完$i$以及其所在子树的问题,且处理完后$i$点存在$0/1$个没有被封住的关键点时的最小代价,转移考虑$i$是否是关键点,随便转就行了 1 #include<bits/stdc++.h> 2 //This code is written by Itst 3 using namespace std; 4 5 inline int read(){ 6 int a = 0; 7 bool f = 0; 8

Kingdom and its Cities - CF613D

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 marri

题解 CF613D 【Kingdom and its Cities】

考虑树形\(DP\),设\(num_x\)记录的为当\(1\)为根时,以\(x\)为子树中重要城市的个数. 那么进行分类讨论: ① 当\(num_x≠0\)时,则需将其所有满足\(num_y≠0\)的儿子\(y\)删去. ② 当\(num_x=0\)时,若满足\(num_y≠0\)的儿子\(y\)个数\(cnt=1\),则直接让\(num\)进行向上传递,若满足\(num_y≠0\)的儿子\(y\)个数\(cnt>1\),则需删去\(x\)本身. 不合法的情况特判掉. 考虑到多次询问和树上点集的

【CF613D】Kingdom and its Cities

题目 题目链接:https://codeforces.com/problemset/problem/613/D 一个王国有 \(n\) 座城市,城市之间由 \(n-1\) 条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重要城市一旦被占领,这座城市就不能通行. 国王定了若干选择重要城市的计划,他想知道,对于每个计划,外敌至少要占领多少个非重要城市,才会导致重要城市之间两两不连通.如果外敌无论如何都不可能导致

codeforces 613D:Kingdom and its Cities

Description 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 daug

CodeForces - 613D:Kingdom and its Cities(虚树+DP)

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 marri

【模板】虚树

核心思想: (听名字高大上,实际上没什么东西……虚树的题主要难在如何操作虚树) 给出$k$个关键点,我们要建出一棵只包含这些关键点和他们$lca$的点数最少的树,以实现$dp$等操作. 标志性的数据范围是$\sum{k}\leq 10^{5}$之类的. 建树方法: 1.将所有关键点按$dfs$序排序. 2.开一个栈表示根到当前点的虚树路径,并把根丢进去. 3.对于每一个关键点$u$: 若栈中只有根这一个元素,则把$u$丢进去. 否则,我们需要弹出栈中所有不在根到$u$路径上的点. 我们用$lca

Travel(HDU 5441 2015长春区域赛 带权并查集)

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2404    Accepted Submission(s): 842 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr

hdu5441

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1225    Accepted Submission(s): 443 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr