poj 1985 Cow Marathon

题面

解题思路

树的直径模板,用树形dp来求,dp[x]表示以x为端点的最大子链长度,d[x]=max(d[y]) (y是x的后继)

代码

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int MAXN = 1000005;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
    return x*f;
}

int n,m;
int head[MAXN],cnt;
int to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
int d[MAXN],ans;
bool vis[MAXN];

inline void add(int bg,int ed,int v){
    to[++cnt]=ed,val[cnt]=v,nxt[cnt]=head[bg],head[bg]=cnt;
}

inline void dp(int x){
    vis[x]=1;
    for(register int i=head[x];i;i=nxt[i]){
        int u=to[i];
        if(vis[u]) continue;
        dp(u);
        ans=max(ans,d[x]+d[u]+val[i]);
        d[x]=max(d[x],d[u]+val[i]);
    }
}

int main(){
    n=rd(),m=rd();
    for(register int i=1;i<n;i++){
        int x=rd(),y=rd(),z=rd();
        add(x,y,z);add(y,x,z);
        char ch=getchar();
        while(ch<'A' || ch>'Z') ch=getchar();
//      cout<<x<<" "<<y<<" "<<z<<endl;
    }
    dp(1);
    printf("%d",ans);
    return 0;
}

还有一种方法也是O(n)的,通过两次dfs或bfs,先随便选一个点,跑dfs到最远,之后再从最远的点跑dfs到最远,所得的就是树的直径。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
const int MAXN = 1e6+10;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
    return x*f;
}

int n,m;
int head[MAXN],cnt;
int to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
int ans,mx,st,dis[MAXN];
bool vis[MAXN];

inline void add(int bg,int ed,int v){
    nxt[++cnt]=head[bg],to[cnt]=ed,val[cnt]=v,head[bg]=cnt;
} 

inline void dfs1(int x,int fa){
    for(register int i=head[x];i;i=nxt[i]){
        int u=to[i];
        if(u==fa) continue;
        dis[u]=max(dis[u],dis[x]+val[i]);
        if(dis[u]>mx){
            mx=dis[u];
            st=u;
        }
        dfs1(u,x);
    }
}

inline void dfs2(int x,int fa){
    for(register int i=head[x];i;i=nxt[i]){
        int u=to[i];
        if(u==fa) continue;
        dis[u]=max(dis[u],dis[x]+val[i]);
        ans=max(ans,dis[u]);
        dfs2(u,x);
    }
}

int main(){
    n=rd();m=rd();
    for(register int i=1;i<n;i++){
        int x=rd(),y=rd(),z=rd();
        add(x,y,z);add(y,x,z);
        char ch=getchar();
        while(ch<'A' || ch>'Z') ch=getchar();
    }
    dfs1(1,0);
    for(register int i=1;i<=n;i++) dis[i]=0;
    dfs2(st,0);
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/sdfzsyq/p/9676976.html