当前位置: 首页 > article >正文

[DFS]

自写组合算法

dfs时,选或不选第k个数,就实现了各种组合。

打印二进制数

vis=[0]*10
def dfs(k,s):
    if k==3:
        print(s)
    else:
        vis[k]=0#选第k个数
        dfs(k+1,s+'0')
        vis[k]=1#不选第k个数
        dfs(k+1,s+'1')
dfs(0,'')

树上DFS

树的重心

树的重心u:

        以树上任意一个结点为根计算它的子树的结点数,如果结点u的最大的子树的结点数最少,那么u就是树的重心。即删除点u后得到两棵或更多棵互不连通的子树,其中最大子树的结点数最小。u是树上最平衡的点。

那么如何计算结点的数量呢,

教父
时间限制: 2000MS内存限制: 65536K

描述

去年芝加哥充满了黑帮斗殴和奇怪的谋杀案。警察局长真的厌倦了所有这些罪行,并决定逮捕黑手党领导人。

不幸的是,芝加哥黑手党的结构相当复杂。已知有n个人与黑手党有关。警方追踪他们的活动有一段时间了,知道他们中的一些人正在互相交流。根据收集到的数据,警察局长建议可以将黑手党等级制度表示为一棵树。黑手党的头目教父是树的根,如果用树中的一个节点表示某个人,则其直属下属就是该节点的子节点。为了阴谋,歹徒只与他们的直接下属和他们的直接主人联系。

不幸的是,虽然警察知道歹徒的通讯方式,但他们不知道任何一对通讯人员中谁是高手。因此他们只有一棵无向的通信树,并且不知道教父是谁。

基于教父希望对黑手党有最大可能的控制的想法,警察局长提出了一个建议,教父是这样一个人,从通信树中删除它后,最大的剩余连接组件的大小尽可能小尽可能。帮助警察找到所有可能的教父,他们会逮捕他们。

输入

输入文件的第一行包含n — 被怀疑属于黑手党的人数(2 ≤ n ≤ 50 000)。让它们从 1 到n编号。

接下来的n -1 行每行包含两个整数。一对a i , b i表示歹徒a i与歹徒b i进行了通信。保证黑帮的通讯形成一棵树。

输出

打印所有被怀疑是教父的人的人数。数字必须按递增顺序打印,并以空格分隔。

样本输入

6
1 2
2 3
2 5
3 4
3 6

示例输出

2 3
import sys
sys.setrecursionlimit(300000)
def dfs(u,fa):
    global maxn
    global num
    tmp=0
    d[u]=1
    for er in edges[u]:#遍历u的子节点
        if er==fa:#不递归父亲
            continue
        dfs(er,u)#递归子节点,计算er这个子树的节点数量
        d[u]+=d[er]#计算以u为根的节点数量
        tmp=max(tmp,d[er])#记录u的最大子树的节点数量
    tmp=max(tmp,n-d[u])#与u父亲相连的另一半节点数量
    #以上计算出了u的最大连通块
    #下面计算疑似教父,如果每一个节点的最大连通块比其他节点的都小,它疑似教父
    if tmp<maxn:#一个疑似教父
        maxn=tmp#更新‘最小的’最大连通块
        num=1
        ans[num]=u#把教父记录在第一个位置
    elif tmp==maxn:
        num+=1
        ans[num]=u#如果疑似教父有多个,记录在后面
maxn=int(1e9)
n=int(input())
edges=[[] for i in range(n+1)]
d=[0]*(n+1)
ans=[0]*(n+1)
num=0
for i in range(n-1):
    a,b=map(int,input().split())
    edges[a].append(b)
    edges[b].append(a)
dfs(1,0)
s=sorted(ans[1:num+1])#对教父排序
for i in range(num):
    print(s[i],end=' ')#按顺序打印所有教父

求树的最长直径(非负权边)

进行两次DFS:

从点a开始找最长的边,其终点为b,再从点b开始找到最长的边,其终点为c,则从b到c就是最长的边,

贪心证明:将树当作绳子,将绳子拉到最长,其上面的节点会下垂,上面任意的节点所能到达的最长边的终点必定是两端点其中的一个,负责绳子一开始就不是拉着最长的状态。

 

import sys
sys.setrecursionlimit(300000)
def dfs(u,fa,d):#用dfs计算从u到每个子节点的距离
    dist[u]=d
    for er,w in edges[u]:
        if er!=fa:#关键,不回头搜素父节点
            dfs(er,u,d+w)
n=int(input())
edges=[[] for i in range(n+1)]
dist=[0]*(n+1)#记录距离
for i in range(n-1):
    a,b,w=map(int,input().split())
    edges[a].append((b,w))
    edges[b].append((a,w))
dfs(1,-1,0)
s=1
for i in range(1,n+1):#找到最远的节点s,s是直径的一个端点
    if dist[i]>dist[s]:
        s=i
dfs(s,-1,0)#从s出发,计算以s为起点,到树上每个节点的距离
t=1
for i in range(1,n+1):#找到直径的另一个端点t
    if dist[i]>dist[t]:
        t=i
print(dist[t])#打印树的直径长度

DFS拓扑排序

欧拉路与DFS

欧拉路:从图中某个点出发,遍历整个图,图中每条边通过且只通过一次。

        图中所有的点连接的边是偶数倍,或者有且仅有起点和终点是奇数边,其他点均为偶数边。

欧拉回路:起点和终点相同的欧拉路。

        图中所有的点连接的边是偶数倍

欧拉路问题:是否存在欧拉路、打印出欧拉路。

 


http://www.kler.cn/a/4682.html

相关文章:

  • 金融项目实战 02|接口测试分析、设计以及实现
  • 如何独立SDK模块到源码目录?
  • 20250112面试鸭特训营第20天
  • 【深度学习】Pytorch:调度器与学习率衰减
  • 浅谈云计算01 | 云计算服务的特点
  • Vue2+OpenLayers调用WMTS服务初始化天地图示例(提供Gitee源码)
  • AutoML-sklearn and torch
  • 学习HM微博项目第4天
  • 12、MySQL数据类型
  • 三个月从功能测试进阶到自动化测试,涨薪5k?你在想啥呢?
  • ICG-PEG-OH 结构式,吲哚菁绿-聚乙二醇-羟基的相关说明
  • 循环神经网络RNN基础
  • 数据结构与算法笔记--堆栈和队列的使用
  • NPM 组件包 epic-geo-ip 等恶意获取主机敏感信息(MPS-2023-8302)
  • P1659拉拉队排练 manacher经典题
  • PyInstaller库的使用及Koch曲线及推广,绘制康托尔集
  • 2023学生党适用的蓝牙耳机有哪些?四款学生党值得入手的蓝牙耳机推荐
  • 软件框架-实现使用@Component@Data@Configuration@Bean(配置类控制类实体类)等方法实现将配置文件从8080端口显示在网页上
  • QT中字符转换
  • 支付宝跳转
  • cron表达式 详解
  • vue3 编写 svg 通用组件 修改颜色和尺寸
  • Unity Animation -- Overview
  • Vue3 の 组合式函数
  • C语言通讯录应用程序:从设计到实现
  • 如何使用python删除一个文件?好用到上头.....