Codeforces 1337C-Linova and Kingdom(tree / DFS / BFS / greedy)

 

   質問の意味:
   開始点は、すべての庭です
  1資本(すなわち、ルート)
  今kをn点近所の工場を、そしてスパイは、植物の点にある
  の首都に庭の幸福+1バックたびの後スパイ
  スパイは最短を取る必要があります  最大の幸せの合計

 

  アイデアは:(簡単にDFS)をコード内のBFSは、各ノードの深さを発見し、その後、各ノードの息子の貢献がした思考を引く
  
  コード:

#include <iostream> 
#include <algorithm> 
#include < string .h> 
#include <cstdio> 
#include < string > 
#include <cmath> 
#include <vector> 
#include <stack> 
#include <queue> 
#include < stack> 
#include <list> 
#include <map> 
#include < set >
 // #include <unordered_map> 
#define Fbo friend bool operator <(node a、node b)
 #define mem(a、b)memset(a、 b、
sizeof(a)) #defineFOR(a、b、c)for(int a = b; a <= c; a ++)
 #define RFOR(a、b、c)for(int a = b; a> = c; a--)
 #define off ios :: sync_with_stdio(0)
 #define sc(a)scanf( "%d"、&a)
 #define pr(a)printf( "%d \ n"、a);
#define SC(n、m)scanf( "%d%d"、&n、&m)
 bool check1(int a){ return(a&(a- 1))== 0truefalse ; } 

名前空間std を使用し ます
typedefペア < intint > pii; 
typedef long  longll;
const  int INF = 0x3f3f3f3f ; // 1e10 
const  int mod = 1e9 + 7 ;
const  int Maxn = 1e5 + 5 ;
const  int N = 2e5 + 5 ;
const  double pi = acos(-1.0 );
const  double eps = 1e- 8 ; 

構造体ノード{ 
    ll b; // 深度 
    ll id; // 位置
} h [N]; 

ベクトル <ll> G [N]; 
ll n、k、u、v;
ll vis [N]; 
ll cnt [N];
ll dis [N]; 
bool cmp(const node&a、const node&b)
{ 
    return ab> bb; 
} 
int main()
{ 
    cin >> n >> k; 
    FOR(i、1、n- 1 
    { 
        cin >> u >> v; 
        G [u] .push_back(v); 
        G [v] .push_back(u); // 最初の先作
    } 
    memset(vis、0sizeof (vis)); 
    h [ 1 ] .b = 0  ;
    FOR(i、1、n){ 
        h [i] .id = i; // 各ポイントにラベルを付ける 
        cnt [i] = 1 ; // 各ノードの最初の寄与は1 
    } 
    vis [ 1 ] = 1 ; 
    queue <ll> q; 
    q.push(1 );
     while(!q.empty())
    { 
        ll start = q.front(); 
        q.pop(); 
        forint i = 0 ; i <G [start] .size(); i ++ 
        { 
            if(! vis [G [start] [i]])
            { 
                vis [G [start] [i]] =1 ; 
                h [G [開始] [i]]。B = h [開始] .b + 1 ; // 各ポイントの深さを取得
                q.push(G [開始] [i]); 
            } 
        } 
    } 
    FOR( i、1、n)dis [i] = h [i] .b; // dis [i]は各ポイント 
    ソートの深度を格納します(h + 1、h + n + 1、cmp); // 最大深度下行降順のノード
    のためのINT I = 1。 I ++; I <= N ){
         int型今= H [I] .ID; // 現在のノード表す
        ため 0をint j =; j <G [now] .size(); j ++)// 現在のノードに息子があるかどうかを確認します
        {
             if(dis [G [now] [j]]> dis [now])// 現在の息子ノードがある場合深さ>ノードの深さ cnt [now] + = cnt [G [now] [j]];   // このノードの息子の寄与を計算するcnt [i]初期値は1 
        } 
        h [i]です。 b- =(cnt [now] -1); // 息子が後で行う貢献を差し引く、1自体を差し引くことを忘れないでください
    } 
    sort(h + 1、h + n + 1、cmp); // 最深部から貪欲ポイントは 
    ll ans = 0 ; 
    FOR(i、1 、k){ 
        ans + =h [i] .b;  
    }を
    cout << ans << endl; 
}

 

 

おすすめ

転載: www.cnblogs.com/AlexLINS/p/12711788.html