HDU 5758 Explorer Bo

来源:互联网 发布:mac地址修改器win8.1 编辑:程序博客网 时间:2024/05/21 10:59

转载声明:http://blog.csdn.net/ShinFeb/article/details/52042364
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5758

题意:
给你一棵树,然后有一个人,可以在树上走,他可以选择从哪个点出发,他要遍历所以的边,每条边的权值是1,他不能回头,就是走上一次走过的边,当走不不可以走的时候,他可以传送到任意一个点,再次开始,输出的是,保证在传送次数最少的情况,能遍历所有边至少1次的最小权值和.

个人感想:
首先我对这道题的DP,看了这么多的题解我都不是特别懂,这个转载是用了贪心的做法,先做好每个边的权值,然后通过奇偶判断是否得修正权值,奇数必定得修.大牛和我说,相当于先插一个叶子点,使树变成偶数叶子节点.然后来修正路径,具体看看代码吧.题解和我的理解也不太清楚(我个人感觉..我尽力了表达了.)希望来个更好的大牛贴,来介绍清楚啊…

ps:我们不能直接把偶数子节点直接对上
这里写图片描述
这看起来好像这样子权值最小,但是!却一共跳了3次了
题目要求是跳的次数最小的情况下权值最小
这里写图片描述
这样的才跳了2次.权值虽然大.

分析:贪心.
代码:

/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * *///#define OUT#include <iostream>using namespace std;#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <sstream>#include <cctype>#include <vector>#include <set>#include <cstdlib>#include <map>#include <queue>//#include<initializer_list>//#include <windows.h>//#include <fstream>//#include <conio.h>#define MaxN 0x7fffffff#define MinN -0x7fffffff#define Clear(x) memset(x,0,sizeof(x))typedef long long ll;const int INF=0x3f3f3f3f;const int maxn=1e6+10;int head[maxn];int du[maxn];int ecnt;int cas;int N;int root;ll ans;ll misdis;struct Edge{  int to;  int next;};Edge edge[maxn*2];int V[maxn];void init(){    misdis=0;    ans=0;    ecnt=0;    memset(head,-1,sizeof(head));    memset(du,0,sizeof(du));}void addedge(int u,int v){   edge[ecnt].to=v;   edge[ecnt].next=head[u];   head[u]=ecnt++;   du[u]++;}int dfs(int s,int fa,int eid){    int son=0;    for(int i=head[s];i!=-1;i=edge[i].next)    {          int v=edge[i].to;          if(v==fa)continue;          son+=dfs(v,s,(i-(i&1)));    }    if(eid==-1)return son;    if(!son)son++;    if(son&1)//如果奇数节点,只会对父边贡献1    {        ans+=1;        V[eid]=1;    }    else    {   ans+=2;        V[eid]=2;    }    return son;}void tdfs(int s,int fa,int ans){    if(ans>misdis) misdis=ans;    for(int i=head[s];i!=-1;i=edge[i].next)    {        int  v=edge[i].to;        if(v==fa)continue;        tdfs(v,s,V[(i-(i&1))]==1?ans-1:ans+1);    }}int main(){#ifdef OUT    freopen("coco.txt","r",stdin);    freopen("lala.txt","w",stdout);#endif     scanf("%d",&cas);     while(cas--)     {         init();         scanf("%d",&N);         int x,y;         for(int i=1;i<N;i++)         {            scanf("%d%d",&x,&y);            addedge(x,y);            addedge(y,x);         }         for(int i=1;i<=N;i++)         {            if(du[i]==1){root=i;break;}         }         ll sum=dfs(root,-1,-1)+1;         if(!(sum&1))         {            printf("%I64d\n",ans);            continue;         }         tdfs(root,-1,0);         ans-=misdis;         cout<<misdis<<endl;         printf("%I64d\n",ans);     }    return 0;}
0 0
原创粉丝点击