AcWing---病毒溯源---树状dp

3465. 病毒溯源 - AcWing题库

思路:

看到题,可以想到树,想到树就会想到递归,所以一般树状dp都是用递归来实现的。那么这道题的递推公式是什么呢,随便抓取一个点当做根节点,将g[i]定义为以i为根节点开始最长变异链的长度,将i的子节点即为j1,j2,j3...所以g[i]=max(g[j1],g[j2],g[j3]....)+1。g[j1],g[j2],g[j3],...就用递归来求即可。

这里树可以用数组来进行表示

可以参考博客:数组模拟邻接表 - AcWing

C++代码:

#include<bits/stdc++.h>
using namespace std;

int h[10010],e[10010],nxt[10010];
int idx;
int N;
int root[10010];//考察哪个点没有父节点
int head;
int path[10010];//最终路径上,节点i的下一个点

void add(int a,int b){
    e[idx]=b;//第idx条边的终点是b
    nxt[idx]=h[a]; //第idx条边的下一条边号为h[a]
    h[a]=idx; //h[a]指向idx这条新边
    idx++;
}

int dfs(int i){ //i为根节点,以节点i为根节点的最长变异链长度
    int res=0;
    if(h[i]==-1){return 1;}
    int v=0;
    /*树形dp大框架,遍历每条边*/
    for(int j=h[i];j!=-1;j=nxt[j]){
        int e_temp=e[j];
        int d_temp=dfs(e_temp);
        if(res<d_temp+1){
            res=d_temp+1;
            v=e_temp;
        }
        else if(res==d_temp+1 && v>e_temp){
            v=e_temp;
        }
    }
    path[i]=v;
    return res;
}


int main(){
    cin>>N;
    
    /*初始化h+path*/
    for(int i=0;i<N;i++){
        h[i]=-1;
        path[i]=-1;
    }
    /*建树*/
    for(int i=0;i<N;i++){
        int k;
        cin>>k;
        for(int j=0;j<k;j++){
            int temp;
            cin>>temp;
            add(i,temp);
            root[temp]=1;
        }
    }

    /*找树的根节点head*/
    for(int i=0;i<N;i++){
        if(root[i]==0){
            head=i;
            break;
        }
    }
    /*dfs*/
    cout<<dfs(head)<<endl;
    /*找路径*/
    cout<<head;
    for(int i=path[head];i!=-1;i=path[i]){
        cout<<' '<<i;
    }
    return 0;
    
}

Python代码:

import os
import sys
h=[-1]*10010
e=[0]*10010
nxt=[0]*10010
root=[0]*10010
path=[-1]*10010
idx=0
head=0
def add(a:int,b:int):
    global idx
    e[idx]=b
    nxt[idx]=h[a]
    h[a]=idx
    idx+=1
def dfs(i:int) -> int:
    res=0
    if h[i]==-1:
        return 1
    v=0
    j=h[i]
    while j!=-1:
        e_temp=e[j]
        d_temp=dfs(e_temp)
        if res<d_temp+1:
            res=d_temp+1
            v=e_temp
        elif res==d_temp+1 and v>e_temp:
            v=e_temp
        j=nxt[j]
    path[i]=v
    return res
N=int(input())

for i in range(N):
    k=list(map(int,input().split()))
    for j in range(1,k[0]+1):
        add(i,k[j])
        root[k[j]]=1
for i in range(N):
    if root[i]==0:
        head=i
        break
print(dfs(head))
end=[]
end.append(head)
i=path[head]
while i!=-1:
    end.append(i)
    i=path[i]
num=[str(i) for i in end]
print(' '.join(num))

这里需要注意几点:

1.在函数中用全局变量需要加global

2.打印0 2 4 6这种,且0之前6之后不能有空格,可以先将0 2 4 6放入list中,并且将这些元素转化成字符,用代码' '.join()来连接。

num=[str(i) for i in end]
print(' '.join(num))

相关推荐

  1. 信号塔(树形dp

    2024-04-06 08:18:06       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-06 08:18:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-06 08:18:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-06 08:18:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-06 08:18:06       20 阅读

热门阅读

  1. 怎么理解React refs,在哪些场景下使用?

    2024-04-06 08:18:06       15 阅读
  2. 03---webpack进阶用法

    2024-04-06 08:18:06       12 阅读
  3. C语言中不常用到的一些函数

    2024-04-06 08:18:06       14 阅读
  4. html的简单使用

    2024-04-06 08:18:06       15 阅读
  5. JDK安全剖析之术语与定义

    2024-04-06 08:18:06       11 阅读
  6. 区块链面试题总结

    2024-04-06 08:18:06       12 阅读
  7. 富格林:合理破除阻挠出金伎俩

    2024-04-06 08:18:06       15 阅读
  8. Verasity开发更新

    2024-04-06 08:18:06       16 阅读
  9. centos7安装k8s

    2024-04-06 08:18:06       15 阅读
  10. Web Form

    2024-04-06 08:18:06       15 阅读
  11. spa、vue、elementUi

    2024-04-06 08:18:06       13 阅读
  12. Visual Studio 2022 配置及设置 One Dark Pro

    2024-04-06 08:18:06       11 阅读