HDU 3848 DFS 树形DP
来源:互联网 发布:无限量流量软件 编辑:程序博客网 时间:2024/05/20 14:18
给你一棵树,找出两个叶子之间的最短距离。
第一种是个纯dfs+稍微的剪枝,从每一个叶子出发,dfs直到找到一个新的叶子,更新最短距离。781ms
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<queue>#define MAXN 10001#define INF 2147483647using namespace std;int n;vector<int>g[MAXN],w[MAXN];int angel[MAXN];int maxx;bool vis[MAXN];void dfs(int ori,int cur,int dis){ if(dis>=maxx) return ; vis[cur]=true; if(angel[cur]==1&&cur!=ori) { maxx=min(maxx,dis); return ; } for(int i=0; i<(int)g[cur].size(); i++) { int t=g[cur][i]; if(!vis[t]&&w[cur][i]+dis<maxx) dfs(ori,t,w[cur][i]+dis); }}int main(){// freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n) { for(int i=0; i<=n; i++) g[i].clear(),w[i].clear(),angel[i]=0; maxx=INF; for(int i=0; i<n-1; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); angel[a]++,angel[b]++; g[a].push_back(b),w[a].push_back(c); g[b].push_back(a),w[b].push_back(c); } for(int i=1; i<=n; i++) if(angel[i]==1) { memset(vis,false,sizeof(vis)); dfs(i,i,0); } printf("%d\n",maxx); } return 0;}
第二种是新接触的树形dp,从任意一个节点出发,dfs回溯,dp[cur][0]表示cur节点到叶子的最短距离,dp[cur][1]表示cur节点到叶子的次短距离。注意dp数组的初始化,(每一个叶子到叶子的最短距离是0)。PS.树形dp,它的原理和名字很像。dp[cur][0]=min{dp[cur][0],dp[u][0]+dis(u,cur)],因为父节点cur的dp值通过子节点来得出,所以通过回溯递归求解每一个节点的dp[][].#include<cstdio>#include<cstring>#include<iostream>#include<vector>#define MAXN 10010#define INF 20000000using namespace std;vector<int>g[MAXN],w[MAXN];int n,dp[MAXN][2],degree[MAXN];bool vis[MAXN];int maxx;void dfs(int cur){ vis[cur]=true; for(int i=0; i<(int)g[cur].size(); i++) { int t=g[cur][i]; if(!vis[t]) { dfs(t); if(w[cur][i]+dp[t][0]<dp[cur][0]) { dp[cur][1]=dp[cur][0]; dp[cur][0]=w[cur][i]+dp[t][0]; } else if(w[cur][i]+dp[t][0]<dp[cur][1]) dp[cur][1]=w[cur][i]+dp[t][0];// printf("cur:%d %d %d\n",cur,dp[cur][0],dp[cur][1]); } } maxx=min(maxx,dp[cur][0]+dp[cur][1]);}int main(){ freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n) { for(int i=0; i<=n; i++) g[i].clear(),w[i].clear(),degree[i]=0; for(int i=1; i<n; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); degree[a]++,degree[b]++; g[a].push_back(b),g[b].push_back(a); w[a].push_back(c),w[b].push_back(c); } for(int i=1; i<=n; i++) { dp[i][0]=dp[i][1]=INF; if(degree[i]==1) dp[i][0]=0; } memset(vis,false,sizeof(vis)); maxx=INF; dfs(1); printf("%d\n",maxx); } return 0;}
- HDU 3848 DFS 树形DP
- hdu 1561 树形dp+背包+dfs
- HDU 2196 Computer 树形DP+dfs预处理
- hdu 2196 Computer dfs / 树形dp
- HDU 1520 Anniversary party (树形dp,dfs+dp)
- HDU1078(树形DP+DFS)
- hdu1520(树形DP+DFS)
- HDU1011树形DP+DFS
- zoj3201 树形DP+DFS
- HDU1561 树形DFS+DP
- HDU 2196 Computer 树形DP(2个dfs)
- hdu 2196 Computer(树形DP,两次dfs)好好看。。。
- hdu 2196 Computer (树形dp+两次dfs遍历)
- HDU 1520 Anniversary party(DFS或树形DP)
- hdu 4707 Pet 树形DP/DFS 简单题
- 动规<树形dp>+dfs (hdu 1520)
- HDU 4616 Game(树形dp,两遍dfs)
- HDU 5293 Tree chain problem dfs序+树形dp
- tftp用法
- C++常量折叠
- 使用GDB调试RB-tree
- sql distinct 用法
- py文件传输
- HDU 3848 DFS 树形DP
- launcher开发1
- 【android日常错误】Android R.java文件丢失,解决方法
- Java基础11:线程;synchronized;延迟加载(懒汉模式);死锁
- 普通充电器给苹果IPHONE/IPAD2充电的USB端的识别电阻的设置
- POJ 3468 A Simple Problem with Integers
- dwr框架中DWRUtil的方法
- SAP IDOC配置开发
- launcher2