POJ1985Cow Marathon[树的直径]

CowMarathon解题报告
本文介绍了一道名为CowMarathon的问题,该问题是关于寻找农场间最远距离以设计一场牛马拉松比赛路线的问题。通过使用深度优先搜索和动态规划的方法,解决如何找到地图上两个最远的农场之间的路径长度。
Cow Marathon
Time Limit: 2000MS Memory Limit: 30000K
Total Submissions: 5117 Accepted: 2492
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 committed to create a bovine marathon for his cows to run. The marathon route will include a pair of farms and a path comprised of a sequence of roads between them. Since FJ wants the cows to get as much exercise as possible he wants to find the two farms on his map that are the farthest apart from each other (distance being measured in terms of total length of road on the path between the two farms). Help him determine the distances between this farthest pair of farms. 

Input

* Lines 1.....: Same input format as "Navigation Nightmare".

Output

* Line 1: An integer giving the distance between the farthest pair of farms. 

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S

Sample Output

52

Hint

The longest marathon runs from farm 2 via roads 4, 1, 6 and 3 to farm 5 and is of length 20+3+13+9+7=52. 

Source


裸题
换一种DP写法
小心不能用f[j][1]来更新f[i],因为是从i节点的不同子树中选
//
//  main.cpp
//  poj1985
//
//  Created by Candy on 9/21/16.
//  Copyright ? 2016 Candy. All rights reserved.
//

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+5;
int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,m,u,v,w,ans=0; char c[2];
struct edge{
    int ne,v,w;
}e[N<<1];
int h[N],cnt=0;
void ins(int u,int v,int w){
    cnt++;
    e[cnt].v=v; e[cnt].w=w; e[cnt].ne=h[u]; h[u]=cnt;
    cnt++;
    e[cnt].v=u; e[cnt].w=w; e[cnt].ne=h[v]; h[v]=cnt;
}
int f[N][2];
void dp(int u,int fa){
    f[u][0]=0;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v,w=e[i].w;
        if(v==fa) continue;
        dp(v,u);
        if(f[v][0]+w>f[u][0]){
            f[u][1]=f[u][0];
            f[u][0]=f[v][0]+w;
        }else{
            if(f[v][0]+w>f[u][1]) f[u][1]=f[v][0]+w;
        }
    }
}
int main(int argc, const char * argv[]) {
    n=read();m=read();
    for(int i=1;i<=m;i++){
        u=read();v=read();w=read();
        ins(u,v,w);
        scanf("%s",c);
    }
    memset(f,-1,sizeof(f));
    dp(1,0);
    for(int i=1;i<=n;i++) ans=max(ans,f[i][1]+f[i][0]);
    printf("%d",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/candy99/p/5893366.html

POJ 1985 是一道经典的图论题目,题目名称为 "Cow Marathon"。这道题目要求在一个无向图中找到一条最长的路径,这条路径满足以下条件: 1. 路径上的所有节点都是中的节点。 2. 路径上的节点不能重复。 为了解决这道题目,我们可以使用深度优先搜索(DFS)或者广度优先搜索(BFS)来遍历图,并找到最长的路径。以下是使用 Java 实现的代码示例: ```java import java.util.*; public class CowMarathon { static class Edge { int to; int weight; Edge(int to, int weight) { this.to = to; this.weight = weight; } } static List<List<Edge>> graph = new ArrayList<>(); static int maxDistance = 0; static int maxNode = 0; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int m = scanner.nextInt(); for (int i = 0; i <= n; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int from = scanner.nextInt(); int to = scanner.nextInt(); int weight = scanner.nextInt(); graph.get(from).add(new Edge(to, weight)); graph.get(to).add(new Edge(from, weight)); } boolean[] visited = new boolean[n + 1]; dfs(1, 0, visited); Arrays.fill(visited, false); dfs(maxNode, 0, visited); System.out.println(maxDistance); } static void dfs(int node, int distance, boolean[] visited) { visited[node] = true; if (distance > maxDistance) { maxDistance = distance; maxNode = node; } for (Edge edge : graph.get(node)) { if (!visited[edge.to]) { dfs(edge.to, distance + edge.weight, visited); } } } } ``` ### 代码说明: 1. **Edge 类**:用于表示图中的边,包含目标节点和边的权重。 2. **graph**:使用邻接表表示图。 3. **maxDistance**:记录最长路径的长度。 4. **maxNode**:记录最长路径的终点节点。 5. **main 方法**:读取输入数据,构建图,并调用深度优先搜索(DFS)方法。 6. **dfs 方法**:深度优先搜索遍历图,更新最长路径的长度和终点节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值