关闭

Tree2cycle hdu4714 贪心

标签: c++hdu贪心
211人阅读 评论(0) 收藏 举报
分类:

Description


给定一棵N个节点的树,去掉这棵树的一条边需要消耗值1,为这个图的两个点加上一条边也需要消耗值1。树的节点编号从1开始。在这个问题中,你需要使用最小的消耗值(加边和删边操作)将这棵树转化为环,不允许有重边。
环的定义如下:
(1)该图有N个点,N条边。
(2)每个顶点的度数为2。
(3)任意两点是可达的。
树的定义如下:
(1)该图有N个点,N-1条边。
(2)任意两点是可达的。

Solution


想到了树链剖分的模型

一棵树是可以分成很多条链的,而这些链又能连成环。那么我们只需要考虑如何去边使得链的数量最少就行了

记节点i的儿子数量为son,那么需要切掉son-2+1条边,记最后剩下tot条链,答案为tot*2+1
良心题库支持扩栈

Code


#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define erg(i, st) for (int i = ls[st]; i; i = e[i].next)
#define N 1000001
#define E N * 2 + 1
struct edge{int x, y, next;}e[E];
inline int read(){
    char ch = getchar(); int x = 0;
    while (ch < '0' || ch > '9'){
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0'){
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return x;
}
int ind[N], ls[N];
inline void addEdge(int &cnt, int x, int y){
    cnt += 1; e[cnt] = (edge){x, y, ls[x]}; ls[x] = cnt; ind[y] += 1;
    cnt += 1; e[cnt] = (edge){y, x, ls[y]}; ls[y] = cnt; ind[x] += 1;
}
int vis[N], ans;
inline int dfs(int now, int fa){
    vis[now] = 1;
    int cnt = 0;
    erg(i, now){
        if (!vis[e[i].y]){
            cnt += dfs(e[i].y, now);
        }
    }
    if (cnt >= 2){
        ans += cnt - 1;
    }
    return cnt < 2;
}
int main(void){
    int n = read();
    int edgeCnt = 0;
    rep(i, 2, n){
        int x = read(), y = read();
        addEdge(edgeCnt, x, y);
    }
    ans = 0;
    int root;
    rep(i, 1, n){
        if (ind[i] == 1){
            root = i;
            break;
        }
    }
    dfs(root, 0);
    printf("%d\n", ans * 2 + 1);
    // printf("%d\n", n * 2 - dis[ans] * 2 + 1);
    return 0;
}
1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

hdu_4714_Tree2cycle(树形DP)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4714 题意:给你N个点N-1条边,形成一个树,让你拆树,并连接成一个环,每拆一次,连接一次,消耗1,...
  • bin_gege
  • bin_gege
  • 2016-05-19 23:17
  • 142

hdu 4714 Tree2cycle

乱搞题,要求用最少的操作把一颗树转化成一个环。其实就是把树分成最少的链,然后连接起来即可,仔细观察树的话会发现,一般一个点的度如果大于1的话,该点必然要断开一些连接,因为最终每个点的度都是2, 然后就...
  • u010697167
  • u010697167
  • 2013-09-09 11:17
  • 1296

贪心算法(二)——一般背包问题

题目 有一个背包,最多放M kg的物体(物体大小不限); 有n个物体,每个物体的重量为Wi,每个物体完全放入背包后可获得收益Pi。问:如何放置能获得最大的收益? 注:背包问题分为两种,若每个...
  • u010425776
  • u010425776
  • 2017-04-05 21:19
  • 1759

【贪心算法】区间调度问题总结

1. 单区间调度问题问题定义:存在单一资源,有一组以时间区间形式表示的资源请求reqs={req-1, req-2, …, req-n},第i个请求希望占用资源一段时间来完成某些任务,这段时间开始于b...
  • hongchh
  • hongchh
  • 2016-08-11 16:07
  • 1874

0-1背包问题、贪心算法、动态规划

0-1背包问题
  • songshiMVP1
  • songshiMVP1
  • 2016-08-29 18:32
  • 4054

HDU-4714 Tree2cycle(树型dp)

传送门:HDU-4714 题意:一棵树有n个节点,有2种操作:①删除1条边;②添加1条边。每次操作花费为1,要求用最小花费使得这棵树变成一个环:整个图有n条边,每个点的度为2且构成1个联通块 题解...
  • qq_31759205
  • qq_31759205
  • 2017-08-10 00:20
  • 82

HDU 4714 Tree2cycle 构造出一种链的方法

Tree2cycle A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need...
  • ipqhjjybj
  • ipqhjjybj
  • 2013-09-08 23:59
  • 1077

树形 DP hdu4714 Tree2cycle

好坑的题,如果不加栈就会re,加栈以后记得交c++ #pragma comment(linker, "/STACK:1024000000,1024000000") 树形dp 思路: 分析出...
  • meixiuxiudd
  • meixiuxiudd
  • 2015-09-03 16:02
  • 283

HDU 4714 Tree2cycle (构造,树形DP)

题意:一个树减去一条边,或者加上一条边的费用都是1,问把这棵树改成一个圆的最小费用。 一个树形dp,不会dp的菜鸟,,,,各种分类讨论。。。 #pragma comment(linker, "/ST...
  • binwin20
  • binwin20
  • 2013-09-08 17:09
  • 1191

hdu4714 Tree2cycle

原题链接:     hdu 4714 Tree2cycle 题目大意:给一棵树节点数最多为1000000 ,把这棵树通过删边 和加边使这棵树变成一个环,其中删边和加边的的代价都为 1,输出最小代价。...
  • zhanghan735
  • zhanghan735
  • 2013-09-09 19:08
  • 348
    个人资料
    • 访问:101348次
    • 积分:6310
    • 等级:
    • 排名:第4584名
    • 原创:514篇
    • 转载:7篇
    • 译文:0篇
    • 评论:27条
    联系我
    QQ:315253566
    最新评论