0w1

CFR 659 E. New Reform ( DFS )

Problem - E - Codeforces
点が全て連結する場合を考えて、辺の数だけ degree = 1の点の数ができるとわかる。つまり、連結成分それぞれについてそれを求めればいい。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e5 + 5;
typedef pair< int, int > pii;

int n, m;
pii road[ MAXM ];

int vis[ MAXN ];
int cc_cnt;
int cc_ecnt[ MAXN ];
int cc_vcnt[ MAXN ];

vector< int > G[ MAXN ];

int ex[ MAXM ];

void dfs( int u ){
    vis[ u ] = 1;
    ++cc_vcnt[ cc_cnt ];
    cc_ecnt[ cc_cnt ] += ex[ u ];
    for( int v : G[ u ] )
        if( !vis[ v ] )
            dfs( v );
}

void solve(){
    for( int i = 0; i < m; ++i ){
        G[ road[ i ].first ].push_back( road[ i ].second ),
        G[ road[ i ].second ].push_back( road[ i ].first );
        ++ex[ road[ i ].first ];
        ++ex[ road[ i ].second ];
    }
    for( int i = 1; i <= n; ++i ){
        if( vis[ i ] ) continue;
        ++cc_cnt;
        dfs( i );
        cc_ecnt[ cc_cnt ] /= 2;
    }
    int ans = 0;
    for( int i = 1; i <= cc_cnt; ++i ){
        if( cc_ecnt[ i ] < cc_vcnt[ i ] )
            ans += cc_vcnt[ i ] - cc_ecnt[ i ];
    }
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio( false );
    cin >> n >> m;
    for( int i = 0; i < m; ++i )
        cin >> road[ i ].first >> road[ i ].second;
    solve();
    return 0;
}