一个网的路

· · 题解

闲话

解题思路

状态设计

状态转移

最终答案

ANS=\sum_{u \in root}\min\{dp_{u,0},dp_{u,2}\}

至于为什么不用管 dp_{u,1},不用我多说了吧?

代码实现

好像没什么要注意的细节。。。

AC 代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int dp[N][3];
bool vis[N];
vector<int> nodes[N];
void dfs(int u)
{
    vis[u]=true;
    int fir=0,sec=0;
    for(int v:nodes[u])
    {
        if(vis[v])continue;
        dfs(v);
        int delta=dp[v][0]-dp[v][1];
        if(delta>fir)sec=fir,fir=delta;
        else if(delta>sec)sec=delta;
        dp[u][0]+=min(dp[v][0]-1,dp[v][2]);
        dp[u][1]+=dp[v][0];
    }
    dp[u][0]+=nodes[u].size()+1;
    dp[u][1]-=fir;
    dp[u][2]=dp[u][1]-sec;
    return;
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int ans=(n-1)-m;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        nodes[u].push_back(v);
        nodes[v].push_back(u);
    }
    for(int i=1;i<=n;i++)if(!vis[i])dfs(i),ans+=min(dp[i][0],dp[i][2]);
    printf("%d",ans);
    return 0;
}