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

时间:2022-07-04 03:03:27

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

求解的方法是bfs或者dfs。先找任意一点,bfs或者dfs找出离他最远的那个点,那么这个点一定是该树直径的一个端点,记录下该端点,继续bfs或者dfs出来离他最远的一个点,那么这两个点就是他的直径的短点,距离就是路径长度。具体证明见http://www.cnblogs.com/*qi/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&colon;1985&colon;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 &lpar;模板题&rpar;&lpar;树的直径&rpar;

    <题目链接> 题目大意: 给定一颗树,求出树的直径. 解题分析:树的直径模板题,以下程序分别用树形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. &lbrack;Android&rsqb;使用Dagger 2依赖注入 - DI介绍(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...

  2. Best 3D Modeling software under Ubuntu

    Blender Blender is the best free and open source 3D modelling program out there by a long shot! The ...

  3. 【BZOJ-4386】Wycieczki DP &plus; 矩阵乘法

    4386: [POI2015]Wycieczki Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 197  Solved: 49[Submit][Sta ...

  4. C&num;对HTML文档的解析

    http://www.2cto.com/kf/201312/268777.html http://jingyan.baidu.com/article/7e44095334bb162fc0e2efad. ...

  5. C&plus;&plus;学习笔记(1)——数据类型占空间大小

    boolean bool 1 byte   character char 1 byte May be signed or unsigned   wchar_t 1 byte     char16_t ...

  6. public void onItemClick&lpar;AdapterView arg0&comma; View view&comma; int position&comma;long arg3&rpar;详解【整理自网络】

    参考自: http://blog.csdn.net/zwq1457/article/details/8282717 http://blog.iamzsx.me/show.html?id=147001 ...

  7. hdu 5611 Baby Ming and phone number(模拟)

    Problem Description Baby Ming collected lots of cell phone numbers, and he wants to sell them for mo ...

  8. Python 常用模块大全(整理)

    https://www.cnblogs.com/jpfss/p/9686050.html

  9. Duplicate复制数据库并创建物理StandBy&lpar;spfile&plus;不同实例名&plus;不同路径&rpar;

    过程和Duplicate复制数据库并创建物理StandBy类似,只是不需要重启数据库. 目的:创建standby,不重启源数据库 1设定环境如下: Primary数据库 IP 172.17.22.16 ...

  10. awk 文本处理工具

    awk: 强大的文本处理工具,擅长对日志文件进行分析: 不仅用于Linux,也是任何环境中现在的功能最强大的数据处理引擎: 语法说明: awk '{pattern + action}' {filena ...