bzoj 1907 树的路径覆盖 贪心

题面

题目传送门

解法

给个链接,贪心和树形dp讲得挺到位的

题解

反正我觉得贪心比较好写,也挺好理解的

时间复杂度:\(O(Tn)\)

代码

#include <bits/stdc++.h>
#define N 10010
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
    x = 0; int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();}
    while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f;
}
struct Edge {
    int next, num;
} e[N * 3];
int cnt, vis[N], ans[N];
void add(int x, int y) {
    e[++cnt] = (Edge) {e[x].next, y};
    e[x].next = cnt;
}
void dfs(int x, int fa) {
    ans[x] = 1; int tot = 0;
    for (int p = e[x].next; p; p = e[p].next) {
        int k = e[p].num;
        if (k == fa) continue; dfs(k, x);
        ans[x] += ans[k];
        if (!vis[k]) tot++;
    }
    if (tot >= 2) ans[x] -= 2, vis[x] = 1;
    if (tot == 1) ans[x]--;
}
int main() {
    int T; read(T);
    while (T--) {
        int n; read(n); cnt = n;
        for (int i = 1; i <= n; i++)
            e[i].next = 0, vis[i] = 0, ans[i] = 0;
        for (int i = 1; i < n; i++) {
            int x, y; read(x), read(y);
            add(x, y), add(y, x);
        }
        dfs(1, 0); cout << ans[1] << "\n";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/copperoxide/p/9477047.html

时间: 2024-10-13 09:52:34

bzoj 1907 树的路径覆盖 贪心的相关文章

bzoj 1907: 树的路径覆盖【贪心+树形dp】

我是在在做网络流最小路径覆盖的时候找到这道题的 然后发现是个贪心+树形dp \( f[i] \)表示在\( i \)为根的子树中最少有几条链,\( v[i] \) 表示在\( i \)为根的子树中\( i \) 是( 0)否(1)为一条链的端点 然后贪心转移即可(有链端点则连起来) #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=10005; i

BZOJ 1907 树的路径覆盖 树形DP

题目大意:给定一棵树,求最小路径覆盖 数据范围1W,看到还想跑网络流来着= = 不过算了明明树形DP这么水还是不要用网络流这种大杀器为好 首先将所有的链都考虑成以链上所有点的LCA为转折点的V字形 那么点有两种:转折点和非转折点 因此我们选择两种状态进行转移:还会和父亲组成链的状态和成为转折点的状态 转移就自己YY算了 时间复杂度是线性的 #include <cstdio> #include <cstring> #include <iostream> #include

1907: 树的路径覆盖

1907: 树的路径覆盖 Time Limit: 5 Sec  Memory Limit: 259 MBSubmit: 506  Solved: 219[Submit][Status][Discuss] Description Input Output Sample Input 1 7 1 2 2 3 2 4 4 6 5 6 6 7 Sample Output 3 HINT Source Play with Tree By Amber 题解:贪心题么么哒,直接DFS一遍就好啦 1 /******

【bzoj1907】树的路径覆盖 树形dp

题目描述 输入 输出 样例输入 1 7 1 2 2 3 2 4 4 6 5 6 6 7 样例输出 3 题解 树形dp 设f[x]表示以x为根的子树完成路径覆盖,且x为某条路径的一端(可以向上延伸)的最小路径数,g[x]表示以x为根的子树完成路径覆盖,且x不为某条路径的一端的最小路径数. 那么考虑点x,只有三种情况:单独成路径.与一条子树的链成路径.与两条子树的链成路径. 这三种情况分别对应三种状态转移方程,具体见代码. 然而看到网上题解大把大把的贪心我也是醉了qaq #include <cstd

BZOJ1907 树的路径覆盖

ydc题解上写着贪心,后来又说是树形dp...可惜看不懂(顺便骗三连) 其实就是每个叶子开始拉一条链,从下面一路走上来,遇到能把两条链合起来的就合起来就好了. 1 /************************************************************** 2 Problem: 1907 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:112 ms 7 Memory:1396 kb 8 *****

求一棵树的最小路径覆盖

相关题目:http://codeforces.com/problemset/problem/618/D 有向图的最小路径覆盖(所有点)可以用二分图来解,n-最大匹配. 无向图的最小路径覆盖(所有点)似乎是比较困难的问题 那么对于特殊的无向图 - '树'来说,求它的最小路径覆盖有什么好用的方法呢? 首先我们可以考虑用dp求解,维护每棵子树留下向上可延伸路径的情况下能获得的最小路径覆盖是多少f[i][1],以及每棵子树不留下向上可延伸路径的情况下能获得的最小路径覆盖f[i][0].转移在这里不多赘述

Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)

题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上有一个点的度数是n-1,那么必然需要走一条生成树上的边,此时答案为x+y*(n-2). 否则可以不走生成树上的边,则答案为y*(n-1). 再考虑x<y的情况,那么应该尽量走生成树上的边,由于树上没有环,于是我们每一次需要走树的一条路,然后需要从非生成树上的边跳到树的另一个点上去, 显然跳的越少越好,于

SPOJ UOFTCG - Office Mates (树的最小路径覆盖)

UOFTCG - Office Mates no tags Dr. Baws has an interesting problem. His N graduate students, while friendly with some select people, are generally not friendly with each other. No graduate student is willing to sit beside a person they aren't friends

BZOJ 2150 部落战争(最小路径覆盖)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2150 题意:一个n*m的国家,有些是障碍.对于一支军队,每次只能走C*R的格式(比如马是走1*2的格式),而且只能从上往下走.每个格子只能被一个军队经过.问最少需要多少军队可以遍历完所有格子? 思路:上下能连边的连边.最后就是最小路径覆盖. int a[N][N],n,m; char s[55][55]; int ID(int i,int j) { return (i-1)*m+j;