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

析:很明显这是一个树上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. Oracle重建临时表空间

    [oracle@hd58 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Wed Jun 27 11:58:25  ...

  2. 分享Axure RP8.0激活码一份

    用户名:aaa 注册码:2GQrt5XHYY7SBK/4b22Gm4Dh8alaR0/0k3gEN5h7FkVPIn8oG3uphlOeytIajxGU

  3. Flask - 第一篇

    首先,要看你学没学过Django 如果学过Django 的同学,请从头看到尾,如果没有学过Django的同学,并且不想学习Django的同学,轻饶过第一部分 一. Python 现阶段三大主流Web框 ...

  4. Python实践练习:多重剪贴板

    题目 假定你有一个无聊的任务,要填充一个网页或软件中的许多表格,其中包含一些文本字段.剪贴板让你不必一次又一次输入同样的文本,但剪贴板上一次只有一个内容.如果你有几段不同的文本需要拷贝粘贴,就不得不一 ...

  5. Newtonsoft.Json(Json.Net)学习

    转自原文 Newtonsoft.Json(Json.Net)学习笔记 Newtonsoft.Json,一款.NET中开源的Json序列化和反序列化类库.软件下载地址: http://www.newto ...

  6. python学习——练习题(11)

    """ 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1 1 2 ...

  7. data-ajax="false"

    转自:https://yq.aliyun.com/ziliao/265393 最近在做一个项目,由于涉及到跨平台性,所以采用了jquerymobile这个框架,在开发过程中,一开始为了图测试方便,采用 ...

  8. 利用CopyOnWriteArrayList解决并发修改异常问题

    一.需求 多个线程再获取同一个集合里面的数据同时,修改集合中的数据. 二.有问题的写法 package com.duchong.juc; import java.util.ArrayList; imp ...

  9. effective javascript 学习心得

    第2条:理解JavaScript的浮点数 1.js数字只有一种类型 2.见代码 /** * Created by Administrator on 2017/7/2. */ console.log(& ...

  10. 字符编码 ASCII,Unicode和UTF-8的关系

    转自:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143166410626 ...