每日趣味算法(2015年9月18日)
2015-09-18 23:40
246 查看
题目来自:HDU 3848 CC On The Tree(树上叶子结点最近点对)
题意:给定一棵树,可以知道,任意两个叶子之间都有一个距离,求距离的最小值,也就是说求隔得最近的两个叶子的最短距离是多少。
如果要求两个叶子节点之间距离的最大值,事实上这就是“树的直径”的定义。可以进行两次BFS即可。复杂度O(n)。
对于本题,对图进行分析, 可知对于任意两个叶子节点, 它们的最短路径必有共同祖先. 故对于每一个非叶子节点, 保存这个节点到离它最近的叶子节点和第二近的叶子节点的距离. 只需要进行一次dfs就可以求出所有节点到离它最近和第二近的叶子节点的距离, 复杂度为O(n),然后以O(n)的复杂度又可以更新出最优解.
下面是AC代码:
题意:给定一棵树,可以知道,任意两个叶子之间都有一个距离,求距离的最小值,也就是说求隔得最近的两个叶子的最短距离是多少。
如果要求两个叶子节点之间距离的最大值,事实上这就是“树的直径”的定义。可以进行两次BFS即可。复杂度O(n)。
对于本题,对图进行分析, 可知对于任意两个叶子节点, 它们的最短路径必有共同祖先. 故对于每一个非叶子节点, 保存这个节点到离它最近的叶子节点和第二近的叶子节点的距离. 只需要进行一次dfs就可以求出所有节点到离它最近和第二近的叶子节点的距离, 复杂度为O(n),然后以O(n)的复杂度又可以更新出最优解.
下面是AC代码:
#include<cstdio> #include<cstring> #include<iostream> #include<vector> using namespace std; const int maxn=10005,inf=INT_MAX ; int dp[maxn][2],n; struct node { int to,len; node(int to=0,int len=0):to(to),len(len){} }; vector<node>G[maxn]; void add(int from,int to,int len) { G[from].push_back(node(to,len)); G[to].push_back(node(from,len)); } void init() { for(int i=0;i<=n;i++) G[i].clear(); fill(&dp[0][0],&dp[maxn][0],inf); } void dfs(int u,int p) { if(G[u].size()==1)//如果u是叶子节点 { dp[u][0]=0;//u节点到叶子节点的最短距离自然为0 return ; } for(int i=0;i<G[u].size();i++)//枚举所有与u相邻的节点 { int v=G[u][i].to,len=G[u][i].len; if(v==p) continue; dfs(v,u);//先求出v节点到叶子节点的最短距离,以方便更新u节点到叶子节点的最短距离 if(dp[u][0]>dp[v][0]+len)//如果u节点到叶子节点的最短距离大于v节点到叶子节点的最短距离加上u-v边长,则更新 { dp[u][1]=dp[u][0];//原来最短的变成第二短的了 dp[u][0]=dp[v][0]+len;//更新最短的 } else if(dp[u][1]>dp[v][0]+len) dp[u][1]=dp[v][0]+len;//如果可以更新第二短的 } } int main() { //freopen("in.txt","r",stdin); int from,to,len; while(~scanf("%d",&n),n) { init(); for(int i=1;i<n;i++) { scanf("%d%d%d",&from,&to,&len); add(from,to,len); } if(n==2) { printf("%d\n",len); continue; } for(int i=1;i<=n;i++) if(G[i].size()>1)//找到非叶子节点 { dfs(i,-1); break; } int ans=inf; for(int i=1;i<=n;i++)//对非叶子节点进行选取 if(dp[i][0]&&dp[i][1]&&dp[i][0]!=inf&&dp[i][1]!=inf) ans=min(ans,dp[i][0]+dp[i][1]); printf("%d\n",ans); } return 0; }
相关文章推荐
- 点击单个cell高度变化的动画效果
- zx一篇让Java程序猿随时可以翻看的Oracle总结
- 天天学设计模式2-策略模式
- log等级
- 开发经验交流-----ServiceUtil工具类
- Android的jni学习之路--第一篇
- js表单验证,要求数字
- 学习日志---hdfs配置及原理+yarn的配置
- Apache POI
- Apache fileUpload
- spring3.0 MVC的简单示例
- PING命令 原理
- ksh 0403 031问题出现
- maven多模块项目
- 零基础学python-18.4 函数对象:间接调用函数
- sql查询最大的见多了,查询第二的呢???
- 零基础学python-18.4 函数对象:间接调用函数
- 手把手教你生成二维码-google.zxing
- php解析html类库simple_html_dom
- java中创建高效、可靠的高速缓存(1)