关闭

HDU-4714 Tree2cycle(树型dp)

标签: 树型dp
95人阅读 评论(0) 收藏 举报
分类:

传送门:HDU-4714

题意:一棵树有n个节点,有2种操作:①删除1条边;②添加1条边。每次操作花费为1,要求用最小花费使得这棵树变成一个环:整个图有n条边,每个点的度为2且构成1个联通块

题解:树型dp

dp以u为根节点的子树时时记录2种状态:①将子树变成一条链且其中一端为u的最小花费;②将子树变成一条链的最小花费

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MX  = 1e6 + 5;
const int inf = 0x3f3f3f3f;
struct Edge {
    int v, nxt;
} E[MX * 2];
int head[MX], tot, n, m;
void add(int u, int v) {
    E[tot].v = v;
    E[tot].nxt = head[u];
    head[u] = tot++;
}
void init() {
    for (int i = 1; i <= n; i++) head[i] = -1;
    tot = 0;
}
int f[MX], dp[MX];
void dfs(int u, int fa) {
    f[u] = dp[u] = 0;
    int cnt1 = inf, cnt2 = inf, sz = 0;
    for (int i = head[u]; ~i; i = E[i].nxt) {
        int v = E[i].v;
        if (v == fa) continue;
        dfs(v, u);
        f[u] += dp[v];
        dp[u] += dp[v];
        if (f[v] - dp[v] < cnt1) {
            cnt2 = cnt1;
            cnt1 = f[v] - dp[v];
        } else if (f[v] - dp[v] < cnt2) cnt2 = f[v] - dp[v];
        sz++;
    }
    if (sz > 0) {
        f[u] = min(f[u] + 2 * sz, f[u] + cnt1 + 2 * (sz - 1));
        dp[u] = min(dp[u] + 2 * sz, dp[u] + min(cnt1 + cnt2 + 2 * (sz - 2), cnt1 + 2 * (sz - 1)));
    }
}
int main() {
    int T;
    //freopen("in.txt", "r", stdin);
    scanf("%d",&T);
    while (T--) {
        scanf("%d", &n);
        init();
        for (int i = 1, u, v; i < n; i++) {
            scanf("%d%d", &u, &v);
            add(u, v); add(v, u);
        }
        dfs(1, -1);
        printf("%d\n", dp[1] + 1);
    }
    return 0;
}


0
0
查看评论

HDU 4714 Tree2cycle(树型DP)

解题思路: 将一棵树变成一个环,如果一个结点的分叉数目大于等于2,则将它与父节点断开,并且断开子结点数目sum - 2条边,并再次连接sum-2个儿子形成一条直链然后这条游离链与另一条游离链相连,共需要2*(sum-1)个操作,如果该结点为根结点,则一共需要2 * (sum - 2)种操作。 #...
  • u013967323
  • u013967323
  • 2015-03-19 09:36
  • 438

树形DP 洛谷P2014 选课

P2014 选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)...
  • sdfzwzac
  • sdfzwzac
  • 2017-07-10 01:04
  • 83

CodeForces 101D Castle(树形dp)

题意:给出一棵树,每条边有一个权值,问到达所有节点的路程长度最小平均值是多少。 思路:对于一个结点i,假设它有son[I]棵子树,子树中所有边长两倍是T[I],到达所有节点的距离和的最小值为 dp[I],那么可以得到状态转移方程 dp[I] = sigma(dp[v]) + (son[I]-so...
  • u014664226
  • u014664226
  • 2016-06-10 20:59
  • 586

Codeforces 633 F The Chocolate Spree(树形dp,两条不相交链节点权值和最大)

题目链接: Codeforces 633 F The Chocolate Spree 题意: 给一个nn个节点的树和n−1n-1条边,每个点有一个权值,从树中选择两条不相交的链(无公共节点)使得两条链上节点权值和最大? 数据范围:n≤105,value[i]≤109n\leq 10 ...
  • Ramay7
  • Ramay7
  • 2016-08-03 13:49
  • 463

Problem B: [noip2016十连测第五场]walk (树形dp)

Problem B: [noip2016十连测第五场]walk Time Limit: 20 Sec  Memory Limit: 233 MB Submit: 7  Solved: 6 [Submit][Status]...
  • clover_hxy
  • clover_hxy
  • 2016-11-16 16:58
  • 416

HDU 5293 TREE CHAIN PROBLEM LCT+树形DP

题解链接 代码链接 链接 Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T...
  • qq574857122
  • qq574857122
  • 2015-07-22 12:35
  • 1034

[BZOJ4292][PA2015]Równanie 枚举

f(n)最大值为18* 81=1458。枚举f(n),判断f(f(n)*k)是否等于f(n) 即可。 代码:#include<iostream> #include<cstdio> #define ll long long using namespace std; ll k;...
  • DOFYPXY
  • DOFYPXY
  • 2017-10-17 18:31
  • 62

hdu4714 Tree2cycle

原题链接:     hdu 4714 Tree2cycle 题目大意:给一棵树节点数最多为1000000 ,把这棵树通过删边 和加边使这棵树变成一个环,其中删边和加边的的代价都为 1,输出最小代价。 题目分析:由于最终要形成一个环其拥有的的边一定为n,故可以只讨论...
  • zhanghan735
  • zhanghan735
  • 2013-09-09 19:08
  • 359

hdu4714 Tree2cycle

下午心血来潮找来cjx第一次两人训练一套难度很低题目,就差这道思路正确不敢写,现在补一下。 题意:给你一棵树,每次删除一条边和增加一条边费用都是1,问最少的花费把一棵树变成 一条环。 思路:随手画了几个样例,发现不存在最少花费的策略,结果是唯一的。只要dfs序一遍判断每个点度数,大于2就说明...
  • yexiaohhjk
  • yexiaohhjk
  • 2017-04-30 21:51
  • 487

树型dp

树型动态规划     树本身就是一个递归的结构,所以在树上进行动态规划或者递推是最合适不过的事情。     必要条件:子树之间不可以相互干扰,如果本来是相互干扰的,那么我们必须添加变量使得他们不相互干扰。 Par...
  • XerxesSimon
  • XerxesSimon
  • 2016-04-09 15:54
  • 268
    个人资料
    • 访问:57198次
    • 积分:2805
    • 等级:
    • 排名:第15065名
    • 原创:230篇
    • 转载:4篇
    • 译文:0篇
    • 评论:7条
    最新评论