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

析:很明显这是一个树上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. java之IO整理(下)

    一:对象的序列化 对象序列化就是把一个对象变为二进制数据流的一种方法. 一个类要想被序列化,就行必须实现java.io.Serializable接口.虽然这个接口中没有任何方法,就如同之前的clone ...

  2. 为什么 ReactJS 不适合复杂的前端项目?

    问题一:ReactJS组件难以在复杂交互页面中复用 ReactJS中的最小复用单位是组件.ReactJS的组件比AngularJS的Controller和View 要轻量些. 每个组件只需要前端开发者 ...

  3. Change R source code

    If you'd like to simply test out the effect of that change in an interactive R session, you can do s ...

  4. python开发_python中的list操作

    对python中list的操作,大家可以参考: Python list 操作 以下是我个人的笔记: ============================================ Add b ...

  5. 恒大威武!关于SQL的一些基础知识整理回顾

    首先的首先,恒大威武! 开始正题. 关系代数: 目前主流的关系型数据库,是建立在关系代数的基础上的,即他的数学支撑是关系代数. 关系代数主要包括如下几个二目运算:并运算union.交运算interse ...

  6. 引用rtmp编译报错:rtmp.obj : error LNK2001: 无法解析的外部符号 __imp__timeGetTime@0

    如题vs下引用librtmp的时候报错:rtmp.obj : error LNK2001: 无法解析的外部符号 __imp__timeGetTime@0 在link 里加入 winmm.lib 就可以 ...

  7. Android MVP模式简单易懂的介绍方式 (三)

    Android MVP模式简单易懂的介绍方式 (一) Android MVP模式简单易懂的介绍方式 (二) Android MVP模式简单易懂的介绍方式 (三) 讲完M和P,接下来就要讲V了.View ...

  8. eureka快速剔除失效服务

    eureka服务端配置 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓 ...

  9. 网卡流量监控脚本 ( Shell )

    #!/bin/bash # Traffic Monitor # author: Xiao Guaishou get_traffic_info(){ recv=`cat /proc/net/dev | ...

  10. hibernate中 criteria.setProjection(Projections.rowCount()).uniqueResult()为null的Bug

    在hibernate中,在查询总数时,会使用如下方法; public Integer getCount(final DetachedCriteria detachedCriteria) {       ...