HDU 5758 Explorer Bo(树形DP)

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5758

【题目大意】

  给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次数尽量少的情况下至少经过每条路一遍啊,同时最小化走过的路程总长度。输出路程总长度。

【题解】

  首先,对于传送次数尽量少这个条件,我们很容易发现,当且仅当每次出发点和终止点都是叶节点的时候,是最少的,当然在叶节点无法两两匹配的时候,再多走一条链。

  然后就是叶节点的匹配问题,使得匹配后的叶节点连线覆盖全图的路径并且经过的总长度最短,这时候考虑考虑每条边对答案的贡献情况,由于匹配方案不唯一,因此每条边的贡献是利用dp使得耗费最小化的。

  考虑到边每条边最多经过两次,至少经过一次,那么我们枚举这条边两边的情况,在这个点匹配完一些叶节点后还剩下一些链是没有被匹配的时候所能够做到的最小花费。dp[x][i][j]表示,x节点,在当前的遍历情况下,有i个叶节点没有匹配,j条单独链作为最后多走的一条链的最小花费,显然i最多不超过2,j最多不超过1。那么做一个树形DP,将各种情况从子节点转移到根节点即可,由于考虑到图形的特殊性,一开始树的遍历起点不能是叶节点,才能保证每种情况的遍历。

【代码】

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=200005;
int T,n,k,s[5][2],x,y,dp[N][5][2];
long long ans;
vector<int> g[N];
void dfs(int x,int pre){
    if(g[x].size()==1)dp[x][0][1]=dp[x][1][0]=0;
    else dp[x][0][0]=0;
    for(int i=0;i<g[x].size();i++){
        int p=g[x][i];
        if(p==pre)continue;
        dfs(p,x);
        memset(s,60,sizeof(s));
        for(int j=2;j>=0;j--)for(int k=2;k;k--)
        for(int U=0;U<=min(j,k);U++){
            int t=j+k-2*U;
            s[t][0]=min(s[t][0],dp[x][j][0]+dp[p][k][0]+k);
            s[t][1]=min(s[t][1],dp[x][j][0]+dp[p][k][1]+k);
            s[t][1]=min(s[t][1],dp[x][j][1]+dp[p][k][0]+k);
        }memcpy(dp[x],s,sizeof(dp[x]));
    }for(int i=2;i;i--)dp[x][i-1][1]=min(dp[x][i-1][1],dp[x][i][0]);
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)g[i].clear();
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            g[x].push_back(y);g[y].push_back(x);
        }if(n<=2)printf("%d\n",n-1);
        else{
            memset(dp,60,sizeof(dp));
            for(int i=1;i<=n;i++)if(g[i].size()>1){
                dfs(i,-1);
                printf("%d\n",min(dp[i][0][0],dp[i][0][1]));
                break;
            }
        }
    }return 0;
}

  

时间: 2024-10-14 12:18:51

HDU 5758 Explorer Bo(树形DP)的相关文章

hdu 5758 Explorer Bo(树形dp)

题目链接:hdu 5758 Explorer Bo 题意: 给一棵n个点的树,每次任选两个点,然后覆盖两点间的所有边,要求以最少的次数覆盖所有的边,在保证次数最少的情况下要求覆盖边的总次数最小 题解: 详细题解传送门 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 using namespace std; 4 5 const int N=1e5+7; 6 int t,n,x,y,sz[N],

HDU 5758 Explorer Bo

思维,树形dp. 首先选择一个度不为0的节点作为根节点,将树无根转有根. 这题的突破口就是要求瞬间移动的次数最少. 次数最少,必然是一个叶子节点走到另一个叶子节点,然后瞬间移动一次,再从一个叶子节点走到另一个叶子节点,然后瞬间移动一次…… 因为叶子节点总数可能是奇数,可能是偶数,那么接下来要分类讨论一下了. 叶子节点总数为偶数: 这种情况下,叶子节点可以两两配对.如果 下面叶子节点个数是偶数,那么<u,v>这条边通过的次数就是2:如果v下面叶子节点个数是偶数,那么<u,v>这条边通

HDU5758 Explorer Bo 树形dp

我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 考虑每条树边的贡献,贪心的想,肯定是每条树边出现的次数越少越好 由于树链肯定从一个叶子到另外一个叶子的,那么可以想到 1:考虑每条树边下面的子树,如果有奇数个节点,那么出来一条边就可以了,剩下的自己匹配就好 2:如果是偶数条边,出来两条就行了,如果多余两条不如两条更优,少于两条,不符合题意 dp[i

HDU 1011 Starship Troopers(树形DP)

Starship Troopers Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 62   Accepted Submission(s) : 12 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description You, the leader of

hdu 1520Anniversary party(简单树形dp)

Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4310    Accepted Submission(s): 1976 Problem Description There is going to be a party to celebrate the 80-th Anniversary of the

hdu 4044 GeoDefense (树形dp+01背包)

GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 663    Accepted Submission(s): 267 Problem Description Tower defense is a kind of real-time strategy computer games. The goal of towe

HDU 2196 Computer 经典树形DP

一开始看错题了,后来发现原来是在一颗带权的树上面求出距离每一个点的最长距离,做两次dfs就好,具体的看注释? #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #incl

hdu 5452 Minimum Cut 树形dp

Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5452 Description Given a simple unweighted graph G (an undirected graph containing no loops nor multiple edges) with n nodes and m edges. Let T be a spa

HDU 2376 Average distance (树形dp)

Average distance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 588    Accepted Submission(s): 213 Special Judge Problem Description Given a tree, calculate the average distance between two ve