树的直径:树上的最长简单路径。

求解的方法是bfs或者dfs。先找任意一点,bfs或者dfs找出离他最远的那个点,那么这个点一定是该树直径的一个端点,记录下该端点,继续bfs或者dfs出来离他最远的一个点,那么这两个点就是他的直径的短点,距离就是路径长度。具体证明见http://www.cnblogs.com/wuyiqi/archive/2012/04/08/2437424.html 其实这个自己画画图也能理解。

POJ 1985

题意:直接让求最长路径。

可以用dfs也可以用bfs

bfs代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int maxn = ;
int tot, head[maxn];
struct Edge {
int to, next, w;
}edge[maxn];
bool vis[maxn];
void init()
{
tot = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int maxx, pos;
void bfs(int p)//从p开始找到离他最远的那个点,距离保存在maxx当中
{
maxx = -;
memset(vis, false, sizeof(vis));
queue<pii> Q;
vis[p] = true;
pii cur, nex;
cur.first = p; cur.second = ;//pair的first表示节点编号,second表示权值
Q.push(cur);
while (!Q.empty())
{
cur = Q.front();
Q.pop();
for (int i = head[cur.first]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (vis[v]) continue;
vis[v] = true;
nex.first = v; nex.second = cur.second + edge[i].w;
if (maxx < nex.second)//如果找到最大的就替换
{
maxx = nex.second;
pos = v;
}
Q.push(nex);
}
}
}
int main()
{
int n, m;
while (~scanf("%d %d", &n, &m))
{
init();
int u, v, w;
for (int i = ; i < m; i++)
{
scanf("%d %d %d %*s", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
bfs();
bfs(pos);
printf("%d\n", maxx);
}
return ;
}

dfs代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int maxn = ;
int tot, head[maxn];
struct Edge {
int to, next, w;
}edge[maxn];
bool vis[maxn];
void init()
{
tot = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int maxx, pos;
void dfs(int p, int fa, int w)
{
for (int i = head[p]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa || vis[v]) continue;
vis[v] = true;
if (w + edge[i].w > maxx)
{
maxx = w + edge[i].w;
pos = v;
}
dfs(v, p, w + edge[i].w);
vis[v] = false;
}
}
void solve()
{
memset(vis, false, sizeof(vis));
maxx = -;
dfs(, , );
maxx = -;
dfs(pos, , );
printf("%d\n", maxx);
}
int main()
{
int n, m;
while (~scanf("%d %d", &n, &m))
{
init();
int u, v, w;
for (int i = ; i < m; i++)
{
scanf("%d %d %d %*s", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
solve();
}
return ;
}

POJ 1849

题意: 给出一棵树,两个人从给定的点s开始走,走完这棵树最少走的长度。

思路:如果要回到当初的点,根据树的性质,那么一定是将这棵树走了两遍,但是题目要求可以停在任何位置,所以走不到两边,有些边走了一遍,求最小花费,那么一定是最长的那条路径走了一遍,其他都是两遍,这样才是最小花费。仔细想想其实从哪个点开始走并不影响最后的结果。因为不管哪个点肯定都要走完。要使两个人走的简单路径最长,那么这两个人走的路径就是树的最长路径了。所以答案就是:两倍的所有路径权值之和减去树的直径

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int maxn = ;
int tot, head[maxn];
struct Edge {
int to, next, w;
}edge[maxn];
bool vis[maxn];
void init()
{
tot = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int maxx, pos;
void bfs(int p)
{
maxx = -;
memset(vis, false, sizeof(vis));
queue<pii> Q;
pii cur, nex;
cur.first = p; cur.second = ;
vis[p] = true;
Q.push(cur);
while (!Q.empty())
{
cur = Q.front();
Q.pop();
for (int i = head[cur.first]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (vis[v]) continue;
vis[v] = true;
nex.first = v; nex.second = cur.second + edge[i].w;
if (nex.second > maxx)
{
maxx = nex.second;
pos = v;
}
Q.push(nex);
}
}
}
int main()
{
int n, s;
while (~scanf("%d %d", &n, &s))
{
init();
int u, v, w, ans = ;
for (int i = ; i < n; i++)
{
scanf("%d %d %d", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
ans += w * ;
}
bfs(s);
bfs(pos);
printf("%d\n", ans - maxx);
}
return ;
}

POJ 1985 Cow Marathon && POJ 1849 Two(树的直径)的更多相关文章

  1. poj 1985 Cow Marathon

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

  2. poj 1985 Cow Marathon 树的直径

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

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

    http://poj.org/problem?id=1985 题意:给出树,求最远距离. 题意: 树的直径. 树的直径是指树的最长简单路. 求法: 两遍BFS :先任选一个起点BFS找到最长路的终点, ...

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

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

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

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

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

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

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

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

  8. POJ 1985 Cow Marathon (树形DP,树的直径)

    题意:给定一棵树,然后让你找出它的直径,也就是两点中的最远距离. 析:很明显这是一个树上DP,应该有三种方式,分别是两次DFS,两次BFS,和一次DFS,我只写了后两种. 代码如下: 两次BFS: # ...

  9. BZOJ 3363 POJ 1985 Cow Marathon 树的直径

    题目大意:给出一棵树.求两点间的最长距离. 思路:裸地树的直径.两次BFS,第一次随便找一个点宽搜.然后用上次宽搜时最远的点在宽搜.得到的最长距离就是树的直径. CODE: #include < ...

随机推荐

  1. JS设置Cookie,及COOKIE的限制

    在Javascript脚本里,一个cookie 实际就是一个字符串属性.当你读取cookie的值时,就得到一个字符串,里面当前WEB页使用的所有cookies的名称和值.每个cookie除了 name ...

  2. readline函数分析

    函数功能:提示用户输入命令,并读取命令/****************************************************************************/ /* ...

  3. Ruby自学笔记(六)— 循环

    循环结构在编程语言中是不可或缺的,所以Ruby中的循环也有其自定义的规则. 而我们关注循环结构,要知道两个因素:1) 循环的条件:2) 循环执行的内容 Ruby有一些方式来实现循环结构体: 1. ti ...

  4. matplotlib.pyplot 绘图详解 matplotlib 安装

    apt-get install python-matplotlib 转载自: http://www.cnblogs.com/qianlifeng/archive/2012/02/13/2350086. ...

  5. JavaScript API

    HTML5 DOM, BOM, XMLHttpRequest, NodeJS, Framework Framework---------------> jQuery zepto Undersco ...

  6. cf D. Physical Education and Buns

    http://codeforces.com/contest/394/problem/D 题意:给你n个数,然后通过操作使得这n个数变为一个等差数列,操作是可以经过小于等于k次加1或减去1,要使得k尽量 ...

  7. Struts2之ajax初析

    Web2.0的随波逐流,Ajax那是大放异彩,Struts2框架自己整合了对Ajax的原生支持(struts 2.1.7+,之前的版本可以通过插件实现),框架的整合只是使得JSON的创建变得异常简单, ...

  8. 把CSV文件导入到SQL Server表中

    保存数据库数据直接查询select * from tableName 在数据表格的左上角右击——将结果另存为选择路劲保存好的就是.csv格式的数据 有时候我们可能会把CSV中的数据导入到某个数据库的表 ...

  9. 【字符串】【最小表示法】Vijos P1683 有根树的同构问题

    题目链接: https://vijos.org/p/1683 题目大意: 给M棵树,每棵N个点,N-1条边,树边有向,问哪些树同构. 题目思路: [字符串][最小表示法] 用()表示一个节点,那么三个 ...

  10. 使用DateDiff方法获取日期时间的间隔数

    一:用DateDiff方法获取日期时间的间隔数,截图 二:代码 using System; using System.Windows.Forms; using Microsoft.VisualBasi ...