hihocoder 1035 自驾旅行 III(树形dp)

编程入门 行业动态 更新时间:2024-10-08 22:17:29

hihocoder 1035 <a href=https://www.elefans.com/category/jswz/34/1713713.html style=自驾旅行 III(树形dp)"/>

hihocoder 1035 自驾旅行 III(树形dp)

本蒟蒻一道树形dp做了一天,OrzOrzOrz.....菜得难以启齿~~

题解的话这篇博客说得听清楚的~~~

附上大佬的链接:点击打开链接

同时附上本苣菜的代码吧~~

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL inf=0x3f3f3f3f3f3f3f3f;
const int MAXN=1000100;
struct edge_t
{int v,next;LL c0,c1;
}edge[MAXN*2];
int head[MAXN];
int tot;
void init()
{tot=0;memset(head,-1,sizeof(head));
}
void addedge(int u,int v,LL c0,LL c1)
{edge[tot].v=v;edge[tot].c0=c0;edge[tot].c1=c1;edge[tot].next=head[u];head[u]=tot++;
}
//每到一个节点,分情况讨论
//首先没车:
//      分为两种情况:
//      (1).步行出门且回来
//      (2).步行出门人不回来
//如果有车
//      分为三种情况:
//      (1).可以开车出门(开车次数>=0),且如果骑车,人车都回来,否则人必须回来
//      (2).可以开车出门(开车次数>=1),车可以不用回来,但人必须回来
//      (3).可以开车出门(开车次数>=1),车可以没有回来,人也可以没有回来
#define on_foot_ret 0
#define on_foot_noret 1
#define car_people 2
#define nocar_people 3
#define nocar_nopeople 4
bool imp[MAXN];
LL dp[MAXN][5];
void debug(int u)
{printf("Vertex :%d\n",u);printf("On_foot_ret :%lld\n",dp[u][0]);printf("On_foot_noret :%lld\n",dp[u][1]);printf("Car_people :%lld\n",dp[u][2]);printf("Nocar_people :%lld\n",dp[u][3]);printf("Nocar_Nopeople :%lld\n",dp[u][4]);putchar('\n');
}
bool useful[MAXN];
void dfs(int u,int fa)
{useful[u]=imp[u]?true:false;LL chajia1=0;LL chajia2=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v==fa) continue;LL c0=edge[i].c0;LL c1=edge[i].c1;dfs(v,u);if(useful[v]){useful[u]=true;dp[u][on_foot_ret]+=(dp[v][on_foot_ret]+2*c0);chajia1=max(chajia1,dp[v][on_foot_ret]+c0-dp[v][on_foot_noret]);dp[u][car_people]+=min(dp[v][on_foot_ret]+2*c0,dp[v][car_people]+2*c1);chajia2=max(chajia2,min(dp[v][on_foot_ret]+2*c0,dp[v][car_people]+2*c1)-(dp[v][nocar_people]+c0+c1));}}dp[u][on_foot_noret]=dp[u][on_foot_ret]-chajia1;dp[u][nocar_people]=dp[u][car_people]-chajia2;//ttf1表示选择nocar_people,ttf2表示on_foot_noret(遍历最后一个子树的时候没车了)//same表示遍历最后一棵子树的时候还有车LL ttf1=0,ttf2=0,same=0;int match1=-1,match2=-1;LL prettf1=0,prettf2=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v==fa) continue;LL c0=edge[i].c0;LL c1=edge[i].c1;if(useful[v]){LL tmp1=min(dp[v][on_foot_ret]+2*c0,dp[v][car_people]+2*c1)-(dp[v][nocar_people]+c0+c1);LL tmp2=min(dp[v][on_foot_ret]+2*c0,dp[v][car_people]+2*c1)-(dp[v][on_foot_noret]+c0);LL tmp3=min(dp[v][on_foot_ret]+2*c0,dp[v][car_people]+2*c1)-min(dp[v][on_foot_noret]+c0,dp[v][nocar_nopeople]+c1);//ttf1和ttf2不能属于同一棵子树if(tmp1>=ttf1){match1=v;prettf1=ttf1;ttf1=tmp1;}else if(tmp1>prettf1) prettf1=tmp1;if(tmp2>=ttf2){match2=v;prettf2=ttf2;ttf2=tmp2;}else if(tmp2>prettf2) prettf2=tmp2;same=max(same,tmp3);}}LL temp;if(match1!=match2) temp=ttf1+ttf2;else temp=max(ttf1+prettf2,ttf2+prettf1);dp[u][nocar_nopeople]=dp[u][car_people]-max(temp,same);//    if(useful[u]) debug(u);}
int main()
{
//    freopen("in.txt","r",stdin);int n;while(scanf("%d",&n)!=EOF){memset(dp,0,sizeof(dp));memset(imp,false,sizeof(imp));memset(useful,false,sizeof(useful));init();for(int i=1;i<n;i++){int u,v;LL c0,c1;scanf("%d%d%lld%lld",&u,&v,&c0,&c1);addedge(u,v,c0,c1);addedge(v,u,c0,c1);}int w;scanf("%d",&w);for(int i=1;i<=w;i++){int flag;scanf("%d",&flag);imp[flag]=true;}int root=1;dfs(root,-1);printf("%lld\n",min(dp[root][on_foot_noret],dp[root][nocar_nopeople]));}return 0;
}




更多推荐

hihocoder 1035 自驾旅行 III(树形dp)

本文发布于:2024-02-13 11:04:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1757989.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自驾   旅行   hihocoder   III   dp

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!