POJ 1985 Cow Marathon(树的直径)

http://poj.org/problem?id=1985

题意:

有一个树结构, 给你树的全部边(u,v,cost), 表示u和v两点间有一条距离为cost的边. 然后问你该树上最远的两个点的距离是多少?(即树的直径)

分析:

对于树的直径问题, <<算法导论>>(22 2-7)例题有说明.

详细解法: 首先从树上随意一个点a出发, (BFS)找出到这个点距离最远的点b. 然后在从b点出发(BFS)找到距离b点最远的点c. 那么bc间的距离就是树的直径.

证明:

1.    a点在最长路上时, b点一定是最长路的一个端点.

反证:假设b不是端点, 那么最长路的前半段+从a到b的这段必定比原先的最长路更长, 这样就矛盾了.

2.    a点不在最长路上时, a->b一定与最长路有交点(这是一个结论), 且a->b的后半段一定与最长路重合(假设不重合,那么明显又来了一条比最长路还长的路).
即b一定是最长路的端点.

程序实现用的是邻接表来表示树结构.

Head[i]==j 表示与i结点连接的边组成了一条链表, 当中第j条边是这条链的头一个元素, 接着通过j能够找到剩余的(与i连接的)边.

Edge是用来表示每条边的结构.

BFS返回从s结点能走到的最远的点的编号

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=50000+5;
const int maxm=100000+5;

//有向边
struct Edge
{
    Edge(){}
    Edge(int to,int cost,int next):to(to),cost(cost),next(next){}
    int to;   //边尾部
    int cost; //边距离
    int next; //指向下条边
}edges[maxm];
int cnt=0;    //边总数
int head[maxn];//头结点

//加入两条有向边
void AddEdge(int u,int v,int cost)
{
    edges[cnt]=Edge(v,cost,head[u]);
    head[u]=cnt++;
    edges[cnt]=Edge(u,cost,head[v]);
    head[v]=cnt++;
}

//距离
int dist[maxn];

//BFS返回从s出发能到达的最远点编号
int BFS(int s)
{
    int max_dist=0;
    int id=s;
    queue<int> Q;
    memset(dist,-1,sizeof(dist));
    dist[s]=0;
    Q.push(s);

    while(!Q.empty())
    {
        int u=Q.front(); Q.pop();
        if(dist[u]>max_dist)
            max_dist=dist[id=u];
        for(int i=head[u]; i!=-1; i=edges[i].next)
        {
            Edge &e=edges[i];
            if(dist[e.to]==-1)
            {
                dist[e.to]=dist[u]+e.cost;
                Q.push(e.to);
            }
        }
    }
    return id;
}

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2)
    {
        cnt=0;
        memset(head,-1,sizeof(head));
        int u,v,cost;
        char c;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d %c",&u,&v,&cost,&c);
            AddEdge(u,v,cost);
        }
        printf("%d\n",dist[BFS(BFS(u))]);
    }
    return 0;
}
时间: 2024-10-25 15:52:26

POJ 1985 Cow Marathon(树的直径)的相关文章

BZOJ 3363 POJ 1985 Cow Marathon 树的直径

题目大意:给出一棵树.求两点间的最长距离. 思路:裸地树的直径.两次BFS,第一次随便找一个点宽搜.然后用上次宽搜时最远的点在宽搜.得到的最长距离就是树的直径. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 80010 using namespace std; int

poj 1985 Cow Marathon 【树的直径】

题目:poj 1985 Cow Marathon 题意:给出一个树,让你求树的直径. 分析: 树的直径:树上两点之间的最大距离. 我们从任意一点出发,BFS一个最远距离,然后从这个点出发,在BFS一个最远距离,就是树的直径. AC代码: /* POJ:1985 Cow Marathon 2014/10/12/21:18 Yougth*/ #include <cstdio> #include <iostream> #include <algorithm> #include

poj1985 Cow Marathon --- 树的直径

树的直径即树中最长的路径的长度. 用两次dfs,第一次从任意点出发求得一个最远点p, 第二次从p出发求得最远点,这条路径就是最长路,即所求. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include &l

poj 1985 Cow Marathon

题目连接 http://poj.org/problem?id=1985 Cow Marathon Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has committed to create a bovine marathon for his cows to run. The marathon ro

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

Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5496   Accepted: 2685 Case Time Limit: 1000MS Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has com

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

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

POJ 1985 Cow Marathon【树的直径】

题目大意:给你一棵树,要你求树的直径的长度 思路:随便找个点bfs出最长的点,那个点一定是一条直径的起点,再从那个点BFS出最长点即可 以下研究了半天才敢交,1.这题的输入格式遵照poj1984,其实就是把后面的字母无视即可 2.这题数据量没给,所以把数组开得很大才敢交TUT #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <

POJ 3162 Walking Race(树的直径+单调队列)

题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的区间,使得区间中的最大值与最小值的差不超过m. 思路:先找出树的直径的两个端点来,那么树当中的其它节点能走的最大距离一定是到这个两个点当中的其中一个的.所以三遍bfs就可以求出来这个最远的距离,那么,这个最远的距离求出来之后再用两个单调队列来维护最大值和最小值. /*****************

Cow Marathon(树的直径)

传送门 Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5362   Accepted: 2634 Case Time Limit: 1000MS Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has