# 題目

AP325 Q-8-9. 服務中心選位置

# 解題思路

這題是最小支配集問題,我下面的是假解我當時還沒學到這個問題,手搓了個奇怪的解,不過也 AC 了看來我有寫假解的天賦,

#include<bits/stdc++.h>
using namespace std;
#define N 100005
int total=0,chose[N]={0};
vector<int> path[N];
void dfs(int r,int p){//p = parent
    for(auto e:path[r]){
        if(e==p) continue;
        dfs(e,r);
        if(chose[r]==1)
            chose[e]=1;
        else if(chose[e]==0){
            if(p!=-1 && chose[p]==0) chose[p]=2;
            chose[r]=1;
            chose[e]=1;
            total++;
        }
    }
}
int main(){
    int n,num[N]={1},point=1;
    cin>>n;
    for(int i=1,u,v;i<n;i++){
        cin>>u>>v;
        num[u]++;
        num[v]++;
        path[u].push_back(v);
        path[v].push_back(u);
        if(num[u]>num[point]) point=u;
        if(num[v]>num[point]) point=v;
    }
    dfs(point,-1);
    if(chose[point]==0){
        total++;
    } 
    cout<<total;
    return 0;
}

# AC 程式碼

#include<bits/stdc++.h>
using namespace std;
#define Rabbir_Reaper ios::sync_with_stdio(0);cin.tie(0);
#define int long long
const int N = 100005;
vector<int> adj[N];
int dp[N][3];
// 0 : 不選此點,未被支配
// 1 : 不選此點,已被子節點支配
// 2 : 選取此點,已被自己支配
void dfs(int x,int p){
    dp[x][0] = 0;
    dp[x][1] = 1e5;
    dp[x][2] = 1;
    int sum=0;
    for(auto &u:adj[x]){
        if(u == p) continue;
        dfs(u,x);
        dp[x][0] += dp[u][1];
        sum += min(dp[u][1],dp[u][2]);
        dp[x][2] += min({dp[u][0],dp[u][1],dp[u][2]});
    }
    for(auto &u : adj[x]){
        if(u == p) continue;
        dp[x][1] = min(dp[x][1], sum - min(dp[u][1], dp[u][2]) + dp[u][2]);
    }
}
signed main(){
    int n;
    cin>>n;
    n--;
    for(int i=0,u,v;i<n;i++){
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1,-1);
    cout<<min(dp[1][1],dp[1][2]);
}