当前位置: 代码迷 >> 综合 >> POJ 1985. Cow Marathon
  详细解决方案

POJ 1985. Cow Marathon

热度:92   发布时间:2024-02-02 12:34:27.0

链接

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

题意

求边权为正的树形图的直径(树上最长链)

思路一

两次 BFS

随便选一个点 p p ,BFS 求出离点 p p 最远的点 q q

再从点 q q 出发,BFS 求出离点 q q 最远的点 r r

q q r r 的距离就是树的直径

代码

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e5+5;
int n,m;
int cnt,to[N*2],val[N*2],nxt[N*2],head[N];
bool st[N];
int dist[N];
pair<int,int>mx;
void addedge(int u,int v,int w) {cnt++;to[cnt]=v;val[cnt]=w;nxt[cnt]=head[u];head[u]=cnt;
}
void bfs(int u) {queue<int>q;mx.first=0;memset(st,false,sizeof st);q.push(u);dist[u]=0;st[u]=true;while(q.size()) {u=q.front();q.pop();for(int i=head[u];i;i=nxt[i]) {int v=to[i],w=val[i];if(st[v]) continue;st[v]=true;dist[v]=dist[u]+w;if(dist[v]>mx.first) mx=make_pair(dist[v],v);q.push(v);}}
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m;for(int i=1;i<=m;i++) {int u,v,w;char c;cin>>u>>v>>w>>c;addedge(u,v,w);addedge(v,u,w);}bfs(1);bfs(mx.second);cout<<mx.first<<endl; return 0;
}

思路二

树形 DP

首先任选一点为根,记为 r o o t root 并记 d p [ x ] dp[x] 为以 x x 为起点与其朝下所有节点的路径最大值,进行一次树形 DP:

d p [ i ] = max ? j s o n ( i ) ( d p [ i ] , w [ i ] [ j ] + d p [ j ] ) dp[i]=\max \limits_{j \in son(i)}(dp[i],w[i][j]+dp[j])

我们可以发现树的直径其实是以某一点为起点的路径长度的最大值与次大值和,且这两条路径没有重复边,因此我们在进行树形 DP从下到上转移时对 r e s res 进行更新:

r e s = max ? j s o n ( i ) ( r e s , d p [ i ] + d p [ j ] + w [ i ] [ j ] ) res=\max \limits_{j \in son(i)}(res,dp[i]+dp[j]+w[i][j])

代码

#include<iostream>
using namespace std;
const int N=1e5+5;
const int M=2e5+5;
int n,m;
int cnt,to[M],val[M],nxt[M],head[N];
bool st[N];
int dp[N],res;
void addedge(int u,int v,int w) {cnt++;to[cnt]=v;val[cnt]=w;nxt[cnt]=head[u];head[u]=cnt;
}
void dfs(int u) {st[u]=true;for(int i=head[u];i;i=nxt[i]) {int v=to[i],w=val[i];if(st[v]) continue;dfs(v);res=max(res,dp[u]+dp[v]+w);dp[u]=max(dp[u],dp[v]+w);}	
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m;for(int i=1;i<=m;i++) {int u,v,w;char c;cin>>u>>v>>w>>c;addedge(u,v,w);addedge(v,u,w);} dfs(1);cout<<res<<endl;return 0;
}