深搜DFS_桃花(求图的最长路径)

链接:https://www.nowcoder.com/acm/contest/136/C
来源:牛客网
 

题目描述

    桃花一簇开无主,可爱深红映浅红。

                                        ——《题百叶桃花》

    桃花长在桃树上,树的每个节点有一个桃花,调皮的HtBest想摘尽可能多的桃花。HtBest有一个魔法棒,摘到树上任意一条链上的所有桃花,由于HtBest法力有限,只能使用一次魔法棒,请求出Htbest最多可以摘到多少个桃花。

输入描述:

第一行有一个正整数n,表示桃树的节点个数。
接下来n-1行,第i行两个正整数ai,bi ,表示桃树上的节点ai,bi之间有一条边。

输出描述:

第一行一个整数,表示HtBest使用一次魔法棒最多可以摘到多少桃花。

示例1

输入

3
1 2
2 3

输出

3

示例2

输入

3
1 2
1 3

输出

3

示例3

输入

4
1 2
2 3
3 4

输出

4

备注:

对于100%的测试数据:
1 ≤ n ≤ 1000000
数据量较大,注意使用更快的输入输出方式。

 我的代码:

#include <iostream>
#include <memory.h>
#include <cstdio>
using namespace std;
int mx,mxp;
int degree[1000010];
bool visit[1000010];
/*邻接表*/
typedef struct node
{
    int vertex;
    int len;
    node* next;
} pnode;//边表
typedef struct head
{
    int head_node;
    pnode* head_link;
}head_table;//顶点表
head_table head[1000010];
void add_edge(int a,int b,int c)
{
    pnode* temp = new pnode;
    temp->vertex = b;
    temp->len = c;
    temp->next = head[a].head_link;
    head[a].head_node = a;
    head[a].head_link = temp;
}
void dfs(int v,int sum)
{
    visit[v] = true;
    pnode* w;
    bool flag = true;
    for(w = head[v].head_link;w;w=w->next)
      {
          if(!visit[w->vertex])
          {
              flag = false;
              dfs(w->vertex,sum+w->len);
          }
 
      }
      if(flag)
        if(sum>mx)
          {
              mx = sum;
              mxp = v;
          }
          return ;
}
int main()
{
	std::ios::sync_with_stdio(false);
    int a,b,c,kk;
    int n = 0;
    mx = 0;
    int leaf;
    cin>>kk;
    kk--;
    while(kk--)
    {
		cin>>a>>b;
        add_edge(a,b,1);//a点、b点、距离(此题是求节点数,设距离为1,最后再加1) 
        add_edge(b,a,1);//此题是无向图,有向图则不写这行 
        degree[a]++;
        degree[b]++;
        if(a>n)
          n = a;
        if(b>n)
          n = b;
    }
    for(int i=1;i<=n;i++)//枚举找出叶节点
      if(degree[i] == 1)
      {
          leaf = i;
          break;
      }
    memset(visit,false,sizeof(visit));
    dfs(leaf,0);//从叶节点深搜最长
    memset(visit,false,sizeof(visit));
    dfs(mxp,0);//从最“边部”结点搜索另一个最“边部”的结点
    cout<<mx+1<<endl;//本题求的是总节点数,距离+1. 
    return 0;
}

大神代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,i,j,k,h[1000005],ne[2000005],p[2000005],f[1000005],d[1000005];
void dfs(int x)
{
    for(int i=h[x];i;i=ne[i])if(p[i]!=f[x])
    {
        f[p[i]]=x;
        d[p[i]]=d[x]+1;
        dfs(p[i]);
    }
}
int main()
{
    scanf("%d",&n);
    for(i=1;i<n;i++)
    {
        scanf("%d%d",&j,&k);
        p[++m]=k;
        ne[m]=h[j];
        h[j]=m;
        p[++m]=j;
        ne[m]=h[k];
        h[k]=m;
    }
    dfs(1);
    for(i=j=1;i<=n;i++)if(d[i]>d[j])j=i;
    f[j]=d[j]=0;
    dfs(j);
    for(i=1,j=0;i<=n;i++)j=max(j,d[i]);
    cout<<j+1<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aaakkk_1996/article/details/81836939