树的直径【树形dp】【bfs】【poj2631】

题目传送门

树形DP解法

#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<stdio.h>
using namespace std;
const int N=1e6;
int h[N],e[N],w[N],ne[N],idx;
bool st[N];
int cnt[N],ans;
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

void Dp(int u)
{
    //cout<<u<<endl;
    st[u]=true;
    for(int i=h[u];i!=-1;i=ne[i])
    {
        int j=e[i];
        if(st[j]) continue;
        Dp(j);
        ans=max(ans,cnt[u]+cnt[j]+w[i]);
        cnt[u]=max(cnt[u],cnt[j]+w[i]);  // cnt[u] 记录一个节点子树的值

    }
}

int main()
{
    memset(h,-1,sizeof h);
    int a,b,c;
    while(~scanf("%d%d%d",&a,&b,&c))
    {
        add(a,b,c);
        add(b,a,c);
    }
    Dp(1);
    cout<<ans<<endl;
    return 0;
}

bfs解法:负权边不可以用bfs

#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
const int N=1e6;
int h[N],e[N],w[N],ne[N],idx;
bool st[N];
int dis[N],ans,pos;
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

void bfs(int u)
{
    memset(st,0,sizeof st);
    memset(dis,0,sizeof dis);
    st[u]=1;
    dis[1]=0;
    queue<int>q;
    q.push(u);
    while(q.size()){
        int t=q.front();
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(st[j]) continue;
            dis[j]=dis[t]+w[i];
            st[j]=1;
            q.push(j);
            if(ans<dis[j])
            {
                ans=dis[j];
                pos=j;

            }
        }
    }
}

int main()
{
    memset(h,-1,sizeof h);
    int a,b,c;
    while(~scanf("%d%d%d",&a,&b,&c))
    {
        add(a,b,c);
        add(b,a,c);
    }
    bfs(1);
    ans=0;
    bfs(pos);
    cout<<ans<<endl;
    return 0;
}
发布了152 篇原创文章 · 获赞 4 · 访问量 3888

猜你喜欢

转载自blog.csdn.net/qq_43716912/article/details/100151987
今日推荐