P5801 [SEERC2019]Game on a Tree(ACM - ICPC 2019)(树的最大匹配)
完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
const int N = 500007;
int f[N];
vector<int>edge[N];
void dfs(int x, int fa){
for(auto y : edge[x]){
if(y == fa)continue;
dfs(y, x);
f[x] += f[y];
}
if(f[x])f[x] -- ;
else f[x] = 1;
}
int n;
int main(){
scanf("%d", &n);
for(int i = 1; i <= n - 1; ++ i){
int x, y;
scanf("%d%d", &x, &y);
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs(1, 0);
if(!f[1])printf("Bob\n");
else printf("Alice\n");
return 0;
}
树上 DP - 求树的最大匹配数
INT f[maxn], g[maxn];
void dfs(INT node)
{
f[node] = g[node] = 0;
for(int i = head[node]; i; i = edges[i].next)
{
INT to = edges[i].to;
dfs(to);
g[node] += std::max(f[to], g[to]);
}
for(int i = head[node]; i; i = edges[i].next)
{
INT to = edges[i].to;
f[node] = std::max(f[node], g[node] - std::max(f[to], g[to]) + g[to] + 1);
}
}