Codeforces 1337C - Linova and Kingdom(树/DFS/BFS/贪心)
Posted alexlins
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1337C - Linova and Kingdom(树/DFS/BFS/贪心)相关的知识,希望对你有一定的参考价值。
题意:
一开始所有点都是花园
1为首都(即根)
现在n个点里弄k个工厂,而密探都在工厂点上
密探回首都时每经过一个花园时幸福度+1
密探一定走最短路
问最大幸福度之和
思路:BFS求出每个节点的深度,然后再减掉每个节点儿子所做的贡献,思路在代码中(DFS更简单)
代码:
#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)) #define FOR(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 ",a); #define SC(n,m) scanf("%d%d",&n,&m) bool check1(int a) { return (a & (a - 1)) == 0 ? true : false; } using namespace std; typedef pair<int, int> pii; typedef long long ll; 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; struct node { ll b;//深度 ll id;//位置 }h[N]; vector<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 a.b > b.b; } 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, 0, sizeof(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(); for (int i = 0; i < G[start].size(); i++) { if (!vis[G[start][i]]) { vis[G[start][i]] = 1; h[G[start][i]].b = h[start].b + 1; //得到每个点的深度 q.push(G[start][i]); } } } FOR(i, 1, n) dis[i] = h[i].b; //dis[i]存每个点的深度 sort(h + 1, h + n + 1, cmp);//从深度最大的节点往下从大到小排 for (int i = 1; i <= n; i++){ int now = h[i].id;//表示当前的节点 for (int j = 0; 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; }
以上是关于Codeforces 1337C - Linova and Kingdom(树/DFS/BFS/贪心)的主要内容,如果未能解决你的问题,请参考以下文章
Linova and Kingdom CodeForces - 1336A
Linova and Kingdom CodeForces - 1336A (思维)