题意:给定一棵树,然后让你找出它的直径,也就是两点中的最远距离。

析:很明显这是一个树上DP,应该有三种方式,分别是两次DFS,两次BFS,和一次DFS,我只写了后两种。

代码如下:

两次BFS:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue> using namespace std;
const int maxn = 1e5 + 5;
int d[maxn];
bool vis[maxn], vvis[maxn];//vis是BFS的标记,vvis是总的标记
vector<int> G[maxn], w[maxn];
//思路就是先在树上找一个点,然后从这个点开始找,找最远的点,
//然后两从最远的点找最远的点,这个所有点中的最大值就是树的直径
//d[i]表示到结点 i 的最长距离
int bfs(int root){
memset(vis, false, sizeof(vis));
memset(d, 0, sizeof(d));
queue<int> q;
q.push(root);
int ans = root, m = 0;
vis[root] = vvis[root] = true;
while(!q.empty()){
root = q.front(); q.pop();
for(int i = 0; i < G[root].size(); ++i){
int u = G[root][i];
if(vis[u]) continue;
q.push(u);
vis[u] = vvis[u] = true;
d[u] = d[root] + w[root][i];
if(d[u] > m){
ans = u;
m = d[u];
}
}
}
return ans;
} void init(int n){
for(int i = 1; i <= n; ++i){
G[i].clear();
w[i].clear();
vvis[i] = false;
}
} int main(){
int n, m, u, v, l;
char ch;
while(cin >> n >> m){
init(n);
while(m--){
scanf("%d %d %d %c", &u, &v, &l, &ch);
G[u].push_back(v); w[u].push_back(l);
G[v].push_back(u); w[v].push_back(l);
} int ans = 0;
for(int i = 1; i <= n; ++i)
if(!vvis[i]) ans = max(ans, d[bfs(bfs(i))]);//两次BFS,第一次是找最远的点,第二次是找最远点的最远点
cout << ans << endl;
}
return 0;
}

一次DFS:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue> using namespace std;
const int maxn = 1e5 + 5;
int f[maxn], g[maxn], ll[maxn];
vector<int> G[maxn], w[maxn];
//思路主要是找一个点的最远点加次远点就是树的直径 int dfs(int root, int fa){
if(f[root] != -1) return f[root];
if(!G[root].size()) return f[root] = 0;
int m = 0, ans = root;
for(int i = 0; i < G[root].size(); ++i){
int u = G[root][i];
if(u == fa) continue;
if(dfs(u, root) + w[root][i] > m){
m = f[u] + w[root][i];
ans = u;
}
} ll[root] = ans; int mm = 0;
for(int i = 0; i < G[root].size(); ++i){
int u = G[root][i];
if(u == fa) continue;
if(f[u] + w[root][i] > mm && u != ll[root])
mm = f[u] + w[root][i];
}
g[root] = mm;
return f[root] = m;
} void init(int n){
for(int i = 1; i <= n; ++i){
G[i].clear();
w[i].clear();
f[i] = g[i] = ll[i] = -1;
}
} int main(){
int n, m, u, v, l;
char ch;
while(cin >> n >> m){
init(n);
while(m--){
scanf("%d %d %d %c", &u, &v, &l, &ch);
G[u].push_back(v); w[u].push_back(l);
G[v].push_back(u); w[v].push_back(l);
} int ans = 0;
for(int i = 1; i <= n; ++i)
if(f[i] == -1) dfs(i, -1);
for(int i = 1; i <= n; ++i) ans = max(ans, f[i]+g[i]);
cout << ans << endl;
}
return 0;
}

POJ 1985 Cow Marathon (树形DP,树的直径)的更多相关文章

  1. poj:1985:Cow Marathon(求树的直径)

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5496   Accepted: 2685 Case ...

  2. POJ 1985 Cow Marathon (模板题)(树的直径)

    <题目链接> 题目大意: 给定一颗树,求出树的直径. 解题分析:树的直径模板题,以下程序分别用树形DP和两次BFS来求解. 树形DP: #include <cstdio> #i ...

  3. 题解报告:poj 1985 Cow Marathon(求树的直径)

    Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to ge ...

  4. POJ 1985 Cow Marathon (求树的直径)

    Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to ge ...

  5. POJ 3162.Walking Race 树形dp 树的直径

    Walking Race Time Limit: 10000MS   Memory Limit: 131072K Total Submissions: 4123   Accepted: 1029 Ca ...

  6. poj 1985 Cow Marathon

    题目连接 http://poj.org/problem?id=1985 Cow Marathon Description After hearing about the epidemic of obe ...

  7. poj 1985 Cow Marathon 树的直径

    题目链接:http://poj.org/problem?id=1985 After hearing about the epidemic of obesity in the USA, Farmer J ...

  8. poj 1985 Cow Marathon【树的直径裸题】

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4185   Accepted: 2118 Case ...

  9. POJ 1985 Cow Marathon && POJ 1849 Two(树的直径)

    树的直径:树上的最长简单路径. 求解的方法是bfs或者dfs.先找任意一点,bfs或者dfs找出离他最远的那个点,那么这个点一定是该树直径的一个端点,记录下该端点,继续bfs或者dfs出来离他最远的一 ...

随机推荐

  1. 20181122_C#中AOP_使用Unity实现AOP

    一.   使用Unity的AOP实现 a)         整体项目截图: b) 添加Unity的Nuget包, 直接使用最新版就行, 需要添加两个 Unity 和 Unity.Interceptio ...

  2. node 中的定时器, nextTick()和setImmediate()的使用

    1.node中使用定时器的问题在于,它并非精确的.譬如setTimeout()设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms,再次轮到定时器时,已经耽误了4ms. 好了node中 ...

  3. XML的学习

    XML是可扩展标记语言德意思,它和HTML一样都是标记语言(标签语言),不同之处在于XML可拓展,何为可拓展?在HTML中每个标签都有其特定的含义,我们不可以随便写一个标签并赋予其意义,而XML中就可 ...

  4. 第一个Net+Mysql的例子,比想象的简单很多

    1.window下安装mysql,比较简单,完全的图形化界面,不用看文档一路点击下来也ok,注意中间几个configtype选项就可以. 2.安装MySql Net的驱动程序程序,安装完后就是几个dl ...

  5. 第八章 分布式配置中心:Spring Cloud Config

    Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持, 它分为服务端与客户端两个部分. 其中服 ...

  6. Log4j记录日志使用方法

    1.导入相关JAR包 log4j-1.2.15.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.6.1.jar log4jdbc4-1.2.jar 2.配置log4j. ...

  7. windows兼容方式安装python[转]

    Python 是一门很不错的语言,语言简单易学,又不失脚本语言的灵活性,还有海量的第三方库,覆盖的很全面.但也有不少“硬伤”,比如 Python 2.x 和 Python 3.x 版本之间的不兼容等等 ...

  8. C# unsafe模式内存操作深入探索

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...

  9. Java并发之AQS详解(转)

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  10. iOS 上的蓝牙框架 - Core Bluetooth for iOS

    原文: Core Bluetooth for iOS 6 Core Bluetooth 是在iOS5首次引入的,它允许iOS设备可以使用健康,运动,安全,自动化,娱乐,附近等外设数据.在iOS 6 中 ...