C. Valera and Elections (DFS)

题目链接: C. Valera and Elections

题目大意:

 给出n个点,n-1对关系,表示两点之间是否连通,1为连通,2为断。选中一个点,可以修复1到该点的路径上所有坏的边。求最少要选出哪些点。

思路:

  这题还是用dfs,不过做题目的时候还是不会的,看了题解才补了。如果一个点到其父亲的点是坏的,并且他的子节点中所有路径都是好的,那么该点就必须选中。(选出所有路径中最后一条坏的边,只要选中这个点,那么上面所有点都能被修复) 最主要是不知道如何建树,看了题解才知道用vector来建树。 解题过程,存下每一条边,然后dfs建树,用ans数组存答案,(初始化为0,经过标记为2,被选中标记为1)对没条边进行判断,如果是坏的,将这点的ans标记成1,往上搜素,将经过的ans都标记成2,直到根节点1。对每条坏的边都搜素.最后得到答案。

部分细节注释在代码

代码

#include<iostream>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
const int maxn = 100100;
typedef vector<int>V;
V node[maxn]; //存子节点
int vis[maxn], par[maxn], ans[maxn]; //par存父节点 vis用来建树的时候标记是否走过 ,ans存答案。

//存边
struct road {
    int f, t, tp;
}q[maxn];

//建树
void dfs(int rt) {
    vis[rt] = 1;
    for (int i = 0; i<node[rt].size(); ++i) {
        if (!vis[node[rt][i]]) {
            par[node[rt][i]] = rt;
            dfs(node[rt][i]);
        }
    }
}
int main() {
    memset(vis, 0, sizeof(vis));
    memset(ans, 0, sizeof(ans));
    int n, i, j, a, b, c;
    cin >> n;
    for (i = 0; i<n - 1; ++i) {
        cin >> q[i].f >> q[i].t >> q[i].tp;
        node[q[i].f].push_back(q[i].t);
        node[q[i].t].push_back(q[i].f);
    }
    dfs(1);
    for (i = 0; i<n - 1; ++i) {
        //该边坏了
        if (q[i].tp == 2) {
            int pt;

            //判断哪个点是子节点
            if (par[q[i].f] == q[i].t)pt = q[i].f;
            else pt = q[i].t;

            if (ans[pt] == 0) {
                ans[pt] = 1;
                pt = par[pt];
            //如果该点不是这条路径上损坏的最后一个点 当最后一个点循环搜素的时候前面的点就会被覆盖
                while (ans[pt] <= 1) {
                    ans[pt] = 2;
                    if (pt == 1)break;
                    pt = par[pt];
                }
            }
        }

    }
    int res = 0;
    for (i = 1; i <= n; ++i)
        if (ans[i] == 1)res++;
    cout << res << endl;
    int flag = 1;
    for (i = 1; i <= n; ++i)
        if (ans[i] == 1)
            if (flag) {
                cout << i;
                flag = 0;
            }
            else cout << " " << i;
            return 0;
}

猜你喜欢

转载自blog.csdn.net/PinappleMi/article/details/80100334