首页 > 其他分享 >AtCoder Beginner Contest 223 G Vertex Deletion

AtCoder Beginner Contest 223 G Vertex Deletion

时间:2023-05-15 22:24:15浏览次数:37  
标签:AtCoder typedef Beginner Contest int max long son maxn

洛谷传送门

AtCoder 传送门

设 \(f_{u,0/1}\) 为 \(u\) 的子树,\(u\) 是否在匹配内的最大匹配数。

注意到对于一个匹配,在它深度较浅的点上才会被计入答案。

转移大概是 \(f_{u,0}\) 取 \(\sum\limits_{v \in son_u} \max(f_{v,0}, f_{v,1})\),\(f_{u,1}\) 要从儿子中选一个 \(f_{v,0}\),剩下的选 \(\max(f_{v,0}, f_{v,1})\)。先假设全部选 \(\max(f_{v,0}, f_{v,1})\),求出 \(\max\limits_{v \in son_u} f_{v,0} - \max(f_{v,0}, f_{v,1})\),加进 \(f_{u,1}\) 即可。

发现还要求以父亲为根的子树的最大匹配,这个是换根基础操作,转移式同上。减去儿子的 \(\max\) 部分,维护前缀 \(\max\) 和后缀 \(\max\) 即可。注意特殊处理根。

code
// Problem: G - Vertex Deletion
// Contest: AtCoder - AtCoder Beginner Contest 223
// URL: https://atcoder.jp/contests/abc223/tasks/abc223_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const int inf = 0x3f3f3f3f;

int n, head[maxn], len, ans, f[maxn][2], g[maxn][2];

struct edge {
	int to, next;
} edges[maxn << 1];

inline void add_edge(int u, int v) {
	edges[++len].to = v;
	edges[len].next = head[u];
	head[u] = len;
}

void dfs(int u, int fa) {
	int d = -inf;
	for (int i = head[u]; i; i = edges[i].next) {
		int v = edges[i].to;
		if (v == fa) {
			continue;
		}
		dfs(v, u);
		f[u][0] += max(f[v][0], f[v][1]);
		f[u][1] += max(f[v][0], f[v][1]);
		d = max(d, f[v][0] - max(f[v][0], f[v][1]));
	}
	f[u][1] += d + 1;
}

void dfs2(int u, int fa, int f0, int f1) {
	int nf0 = f0, nf1 = f1;
	vector<int> son(1, 0);
	int k = max(f0, f1);
	f0 = f1 = max(f0, f1);
	for (int i = head[u]; i; i = edges[i].next) {
		int v = edges[i].to;
		if (v == fa) {
			continue;
		}
		son.pb(v);
		k += max(f[v][0], f[v][1]);
		f0 += max(f[v][0], f[v][1]);
		f1 += max(f[v][0], f[v][1]);
	}
	if (k == max(f[1][0], f[1][1])) {
		++ans;
	}
	int cnt = (int)son.size() - 1;
	vector<int> pre(cnt + 2), suf(cnt + 2);
	pre[0] = suf[cnt + 1] = (u == 1 ? -inf : nf0 - max(nf0, nf1));
	for (int i = 1; i <= cnt; ++i) {
		int v = son[i];
		pre[i] = max(pre[i - 1], f[v][0] - max(f[v][0], f[v][1]));
	}
	for (int i = cnt; i; --i) {
		int v = son[i];
		suf[i] = max(suf[i + 1], f[v][0] - max(f[v][0], f[v][1]));
	}
	for (int i = 1; i <= cnt; ++i) {
		int v = son[i];
		if (u == 1 && cnt == 1) {
			dfs2(v, u, 0, -inf);
		} else {
			dfs2(v, u, f0 - max(f[v][0], f[v][1]), f1 - max(f[v][0], f[v][1]) + max(pre[i - 1], suf[i + 1]) + 1);
		}
	}
}

void solve() {
	scanf("%d", &n);
	for (int i = 1, u, v; i < n; ++i) {
		scanf("%d%d", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}
	dfs(1, -1);
	dfs2(1, -1, 0, -inf);
	// printf("%d\n", max(f[1][0], f[1][1]));
	printf("%d\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,Beginner,Contest,int,max,long,son,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/17403320.html

相关文章

  • SMU Spring 2023 Contest Round 3(2023年湘潭大学新生赛)
    ProblemA.签到啦从大到小排序,累加大于行李w时输出下标即可intans;voidsolve(){cin>>n>>m;intans=0;vector<int>a(n);for(inti=0;i<n;i++){cin>>a[i];}sort(a.begin(),a.end());reverse(a.begin......
  • SMU Spring 2023 Contest Round 1
    B.ContestPreparation#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring>#include<vector>#include<queue>#include<set>#include<map>#defineinf0x3f......
  • SMU Spring 2023 Contest Round 2
    M.DifferentBilling#include<map>#include<set>#include<cmath>#include<queue>#include<cstdio>#include<vector>#include<climits>#include<cstring>#include<cstdlib>#include<......
  • AtCoder Beginner Contest 301
    title:AtCoderBeginnerContest301categories:算法题解description:咕咕咕tags:-Atcoder-贪心-BFS-DPcover:/img/chino/vec/chino17.jpgkatex:truedate:2023-05-1322:47:31A-OverallWinner(abc301a)题目大意给定一个字符串表示高桥和青木......
  • AtCoder Regular Contest 129 C Multiple of 7
    洛谷传送门AtCoder传送门首先\(\text{7777...777}\)(\(x\)个\(7\))对能被\(7\)整除子串数量的贡献是\(\frac{x(x+1)}{2}\)。把\(n\)分解成若干\(x_i\)使得\(\sum\limits_{i=1}^m\frac{x_i(x_i+1)}{2}=n\),表示每段\(x_i\)个\(7\)。怎么把它们组合在一起呢?一个......
  • AtCoder Beginner Contest 163 F path pass i
    洛谷传送门AtCoder传送门感觉我的做法比较奇葩(容斥,总路径数减去只走点权为\(k\)的路径。设点权为\(k\)的点数为\(c_k\),点权不为\(k\)的点构成的每个连通块大小为\(s_i\),那么\(ans_k=\frac{n(n-1)}{2}-\sum\frac{s_i(s_i-1)}{2}+c_k\)。考虑快速计算\(\su......
  • AtCoder Beginner Contest 207 F Tree Patrolling
    洛谷传送门AtCoder传送门简单树形dp。设\(f_{u,i,p=0/1,q=0/1}\)为\(u\)的子树中被覆盖点数为\(i\),\(u\)有没有被覆盖,\(u\)有没有被选。转移树形背包合并即可,需要分类讨论。要注意如果\(u\)没被覆盖,\(v\)选了,或者\(u\)选了,\(v\)没被覆盖,被覆盖点数要\(+1\)。......
  • AtCoder Beginner Contest 177 F I hate Shortest Path Problem
    洛谷传送门AtCoder传送门设\(f_{i,j}\)为从第\(1\)行到\((i+1,j)\)的最短路。因为我们并不关心最后到达的是哪一个格子,于是强制\(f_{i,j}\)为必须从\((i,j)\)往下走一格到\((i+1,j)\)的最短路。有转移:\[f_{i,r+1}\getsf_{i-1,j}+r+2-j,j\in[l......
  • AtCoder Beginner Contest 152 A-E
    AtCoderBeginnerContest152A-ACorWAvoidsolve(){intn=read(),m=read();puts(n==m?"Yes":"No");}B-ComparingStringsvoidsolve(){intn=read(),m=read();if(m<n)swap(n,m);for(inti=1;i<=m;i++){......
  • 21st UESTC Programming Contest - Preliminary except BCGIKMNPR
    21stUESTCProgrammingContest-PreliminaryexceptBCGIKMNPR OK,那么长的except那我到底写了什么呢(悲,太菜啦) A.能量采集dp+组合数的应用用dp[i][j][p]表示在(i,j)这个点以连续个p结尾的路径数1.首先对于每一个A到达这个格子的方案数是{n-i+m-j\choosen-i}......