//https://vjudge.csgrandeur.cn/contest/532011#problem/F
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define all(a) a.begin(), a.end()
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-4;
const ll mod = 1e9 + 7;
const int N = 2e5 + 5;
/*
基环树上dp方法:
方法1.先考虑树上dp, 再考虑环上dp(将环边链)
方法2.断开环上的一条边(枚举这条边两个端点的情况),再做树形dp
*/
int n, m, xx, yy, dp[N][2];
vector<int> g[N];
void dfs(int x, int fa)
{
//cout << "???? " << x << '\n';
for (int &to : g[x])
{
if (to == fa || x == xx && to == yy || x == yy && to == xx)
continue;
dfs(to, x);
dp[x][0] += dp[to][1];
dp[x][1] += min(dp[to][0], dp[to][1]);
}
dp[x][1]++;
}
void solve()
{
cin >> n >> m;
xx = 0, yy = 1;
for (int i = 1, u, v; i <= n + m; i++)
{
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
int ans = inf;
memset(dp, 0, sizeof dp);
dp[yy][1] = inf;
dfs(xx, -1);
ans = min(ans, dp[xx][1]);
memset(dp, 0, sizeof dp);
dp[yy][0] = inf;
dfs(xx, -1);
ans = min(ans, min(dp[xx][0], dp[xx][1]));
cout << ans << '\n';
}
signed main()
{
IOS;
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}
基环树上dp
最新推荐文章于 2024-07-08 22:12:26 发布