大臣的旅费(求树的最远点对,即树的直径)
2016-03-16 14:48
260 查看
题目大意:求树上两点的最远距离。
分析:可以用DP解,也可以用两次DFS。这里我用两次DFS,树上最远的点对一定是树的直径,而且树上其他点到树的直径某一端点肯定是最远的,第一遍搜找到直径的某个端点,第二次就可以找出来树的直径了,然后就找到了最远的点对啦。关键在于,理解树上任意一点搜一次的最远点一定在直径的某个端点上。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000;
struct node{
int next;
int to;
int w;
}edge[maxn];
int n, cnt, x, maxx;
int head[maxn];
bool vis[maxn];
void dfs(int a, int sum) {
if(maxx < sum) {
maxx = sum;
x = a;
}
for(int i = head[a]; ~i; i = edge[i].next) {
int t = edge[i].to;
if(!vis[t]) {
vis[t] = true;
dfs(t, sum+edge[i].w);
vis[t] = false;
}
}
}
int main() {
while(~scanf("%d", &n)) {
memset(head, -1, sizeof(head));
for(int i = 0; i < n-1; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[i].to = b-1;
edge[i].next = head[a-1];
edge[i].w = c;
head[a-1] = i;
edge[n-1+i].to = a-1;
edge[n-1+i].next = head[b-1];
edge[n-1+i].w = c;
head[b-1] = n-1+i;
}
x = maxx = 0;
memset(vis, 0, sizeof(vis));
vis[0] = true;
dfs(0, 0);
vis[0] = false;
memset(vis, 0, sizeof(vis));
vis[x] = true;
dfs(x, 0);
printf("%d\n", maxx*(11+10+maxx)/2);
}
return 0;
}
分析:可以用DP解,也可以用两次DFS。这里我用两次DFS,树上最远的点对一定是树的直径,而且树上其他点到树的直径某一端点肯定是最远的,第一遍搜找到直径的某个端点,第二次就可以找出来树的直径了,然后就找到了最远的点对啦。关键在于,理解树上任意一点搜一次的最远点一定在直径的某个端点上。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000;
struct node{
int next;
int to;
int w;
}edge[maxn];
int n, cnt, x, maxx;
int head[maxn];
bool vis[maxn];
void dfs(int a, int sum) {
if(maxx < sum) {
maxx = sum;
x = a;
}
for(int i = head[a]; ~i; i = edge[i].next) {
int t = edge[i].to;
if(!vis[t]) {
vis[t] = true;
dfs(t, sum+edge[i].w);
vis[t] = false;
}
}
}
int main() {
while(~scanf("%d", &n)) {
memset(head, -1, sizeof(head));
for(int i = 0; i < n-1; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[i].to = b-1;
edge[i].next = head[a-1];
edge[i].w = c;
head[a-1] = i;
edge[n-1+i].to = a-1;
edge[n-1+i].next = head[b-1];
edge[n-1+i].w = c;
head[b-1] = n-1+i;
}
x = maxx = 0;
memset(vis, 0, sizeof(vis));
vis[0] = true;
dfs(0, 0);
vis[0] = false;
memset(vis, 0, sizeof(vis));
vis[x] = true;
dfs(x, 0);
printf("%d\n", maxx*(11+10+maxx)/2);
}
return 0;
}
相关文章推荐
- 关于字体——Web Fonts
- python面向对象高级编程
- 基本正则表达式,扩展的正则表达式详解
- struts2和mybatis的多例和单例
- C++标准库之substr函数用法
- Spring安全权限管理(Spring Security)
- shiro+redis+springMvc整合配置及说明
- Oracle用户、权限、角色管理
- Activiti 工作流会签开发设计思路
- 5、CSS基础part-3
- CUBRID学习笔记 9 创建示例数据库
- 1、单例模式(饿汉/懒汉)
- 循序渐进开发WinForm项目(3)--Winform界面层的项目设计
- 用numpy里的savetxt()
- Android数据库自动升级
- 《等待你的嫁期》致我的挚爱
- 图片拉伸的几种方式
- 轻松搞定各版本IE兼容问题,IE6,IE7,IE8,IE9,IE10,IE11
- struts2 s:if标签以及 #,%{},%{#}的使用方法等在资料整理
- 积攒一些脚本