CCF之網路延時(樹形dp)

Just Go For It Now發表於2018-09-05

問題描述

試題編號: 201503-4
試題名稱: 網路延時
時間限制: 1.0s
記憶體限制: 256.0MB
問題描述:

問題描述

  給定一個公司的網路,由n臺交換機和m臺終端電腦組成,交換機與交換機、交換機與電腦之間使用網路連線。交換機按層級設定,編號為1的交換機為根交換機,層級為1。其他的交換機都連線到一臺比自己上一層的交換機上,其層級為對應交換機的層級加1。所有的終端電腦都直接連線到交換機上。
  當資訊在電腦、交換機之間傳遞時,每一步只能通過自己傳遞到自己所連線的另一臺電腦或交換機。請問,電腦與電腦之間傳遞訊息、或者電腦與交換機之間傳遞訊息、或者交換機與交換機之間傳遞訊息最多需要多少步。

輸入格式

  輸入的第一行包含兩個整數nm,分別表示交換機的臺數和終端電腦的臺數。
  第二行包含n - 1個整數,分別表示第2、3、……、n臺交換機所連線的比自己上一層的交換機的編號。第i臺交換機所連線的上一層的交換機編號一定比自己的編號小。
  第三行包含m個整數,分別表示第1、2、……、m臺終端電腦所連線的交換機的編號。

輸出格式

  輸出一個整數,表示訊息傳遞最多需要的步數。

樣例輸入

4 2
1 1 3
2 1

樣例輸出

4

樣例說明

  樣例的網路連線模式如下,其中圓圈表示交換機,方框表示電腦:

  其中電腦1與交換機4之間的訊息傳遞花費的時間最長,為4個單位時間。

樣例輸入

4 4
1 2 2
3 4 4 4

樣例輸出

4

樣例說明

  樣例的網路連線模式如下:

  其中電腦1與電腦4之間的訊息傳遞花費的時間最長,為4個單位時間。

評測用例規模與約定

  前30%的評測用例滿足:n ≤ 5, m ≤ 5。
  前50%的評測用例滿足:n ≤ 20, m ≤ 20。
  前70%的評測用例滿足:n ≤ 100, m ≤ 100。
  所有評測用例都滿足:1 ≤ n ≤ 10000,1 ≤ m ≤ 10000。

 

#include <stdio.h>
#include <string.h>
#define MAX 20005

struct Edge
{
    int to;
    int nxt;
};

struct Edge e[MAX*2];//此處記得乘以2
int head[MAX];
int dp[MAX][2];//記錄左子樹和右子樹深度
int tot=0;

int max(int a,int b)
{
    return (a>b)?a:b;
}

void add(int u,int v)
{
    e[tot].to=v;
    e[tot].nxt=head[u];
    head[u]=tot++;
}

void dfs(int u,int par)
{
    int i;
    for(i=head[u];i!=-1;i=e[i].nxt)
    {
        if(e[i].to!=par)
        {
            int v=e[i].to;
            dfs(v,u);
            if(dp[u][0]<dp[v][0]+1)
            {
                dp[u][1]=dp[u][0];//某點的次深度
                dp[u][0]=dp[v][0]+1;//某點的最大深度
            }
            else
            {
                dp[u][1]=(dp[u][1]>dp[v][0]+1)?dp[u][1]:dp[v][0]+1;
            }
        }
    }
    return;
}

int main()
{
    int N,M;
    int i,j,k,a;
    scanf("%d %d",&N,&M);
    for(i=1;i<=N+M;i++)
    {
        head[i]=-1;
        e[i].nxt=-1;
    }
//    for(i=1;i<=N+M;i++)
//    {
//        e[i].nxt=-1;
//    }
    memset(dp,0,sizeof(dp));
    for(i=2;i<=N;i++)
    {
        scanf("%d",&a);
        add(i,a);
        add(a,i);
    }
    for(i=N+1;i<=M+N;i++)
    {
        scanf("%d",&a);
        add(i,a);
        add(a,i);
    }
    dfs(1,0);
    int maxi=-1;
    for(i=1;i<=N+M;i++)
    {
        maxi=max(maxi,dp[i][0]+dp[i][1]);//獲得樹的直徑
    }
    printf("%d\n",maxi);
    return 0;
}

 

相關文章