Codeforces369C Valera and Elections

题意:输入N个点,接下来N-1条边,选出一个点集,修复由这个点到1的路,问最小点集是多少,并输出

题解:树型DP,dp[i]代表及其孩子要选取的点的个数,一个点要选的条件是孩子到这个点的边需要修复且孩子节点下面没有需要修复的路

#include <bits/stdc++.h>
#define maxn 101000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
struct edge{
    int from, to, w;
};
vector<edge>edges;
vector<int >G[maxn];
int dir[maxn], dp[maxn];
vector<int >v;
void dfs(int x){
    dir[x] = 1;
    for(int i=0;i<G[x].size();i++){
        int u = G[x][i];
        edge c = edges[u];
        if(dir[c.to]) continue;
        dfs(c.to);
        if(dp[c.to]) dp[x] += dp[c.to];
        else if(dp[c.to]==0&&c.w == 2) dp[x]++, v.push_back(c.to);

    }
}
void add(int a,int b,int t){
    edges.push_back((edge){a, b, t});
    G[a].push_back(edges.size()-1);
}
int main(){
    int n, a, b, t;
    scanf("%d", &n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d%d", &a, &b, &t);
        add(a, b, t);
        add(b, a, t);
    }
    dfs(1);
    cout<<v.size()<<endl;
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";
    return 0;
}

 

posted on 2018-01-23 19:13  2855669158  阅读(146)  评论(0编辑  收藏  举报

导航