zoukankan      html  css  js  c++  java
  • 图论笔记

    图论 笔记

    一、BFS和DFS

    小性质:DFS的非树边都是返祖边 BFS只有同层或者相邻层之间才有边

    • 01BFS

      边权是0/1的最短路

      在队列里先把和起点距离为0的点压进去

      然后再压距离为1的点 然后正常BFS 就可以求出起点到所有点的最短路

    P1 Travel
    我们考虑当前图的边权为b的子图
    然后我们要在这个上面找1到n的最短路
    这个子图和完全图最多差50w条边
    那么每一次假设当前节点为x 我们要更新一些与他相邻的点
    把这些点有序的写出来 得到一个序列 这个序列由一些区间构成
    这些区间之间有一些缝隙 缝隙的个数最多为50w个 因为每一个缝隙都代表着一条不存在于图中的边
    那么区间的个数最多也为50w个
    所以我们需要:将一个区间中未被删除的点删除 并放入队列中
    用并查集 维护一个链表链表中的点表示未被删除的点
    并查集:f[i]=i 表示未被删除 f[i]=i+1表示已被删除
    那么每次我们这样更新

    int x=getfa(L);
    while(x<=R){
      fa[x]=x+1;	//删除x
      put x in queue;	//将x放入队列中
      x=getfa(x);	//找到下一个未被删去的x
    }
    

    这样每个点最多被删除1次
    复杂度(O(n alpha (n)))

    P2 Bzoj noip2016十连测 D1T3 Walk
    我们考虑把每个val建一个点,假设对于一个val的位置为val+r,i->val[i]+r连一条权值为1的边,val[i]+r->i连一条权值为0的边,那么我们只要让val里面连的那些边边权为0就行了。

    val里面连边暴力连显然比较蠢,我们只连二进制相差一位的val,这样传递一下就相当于连了所有边了。

    那么现在我们一共(2^{20}+200000)个点,(2^{20} imes 20)条边

    01最短路 复杂度和bfs一样

    二、最短路和最短路树

    • Floyd

    • SPFA

    • Dijkstra

    • 最短路图/树

      如果dis(u)+w(u,v)=dis(v),那么在(u,v)之间连一条边 构成最短路图

      他的一棵生成树称为最短路树

    P1 NOIP2017逛公园

    先做出最短路图 找到拓扑序

    (f[i][j])表示当前走到(i),当前的距离-起点到(i)的最短路=(j)的方案数

    (f[i][j]->f[k][j])((i,k))在最短路图中

    (f[i][j]->f[k][j+(w[i][k]-(dis[k]-dis[i]))])((i,k))不再最短路图中

    然后按照拓扑序更新就好了

    P2

    跳过了

    P3 BZOJ3073

    首先构图 对于区间([a,b])和区间([c,d])

    我们新建两个节点(x,y)

    然后把([a,b])的点连到(x)([c,d])的点连到(y)

    然后跑最短路 复杂度(O(nm))

    线段数优化建边 可以把边数做到(m log n +n)

    复杂度 (O(mlog n))

    P4 CF 464E

    跳过了

    P5 Gym - 100959C Jump

    首先建图显然 每个点向他对称得到的(n)个点连边

    但是我们要回答(Q)组询问 每一组询问都得跑一边最短路 设边数为(m=10000n) 那么复杂度是(O(Qm)) 爆炸了

    只能做一次最短路

    发现 从(S)(T) 等价于 从(0)(T-S)(T+S)

    那么只要做从0出发的 到每个点跳了奇数次和偶数次的最短路即可

    复杂度(O(m+Q))

    Tarjan

    在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b 又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。

    • 强连通分量:在一个有向图G中,有一个子图,这个子图每2个点都满 足强连通,我们就叫这个子图叫做 强连通分量。

    • Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索 树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆 栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。

      •Tarjan算法中,有如下定义。

      •DFN[ i ] : 在DFS中该节点被搜索的次序(时间戳)

      •LOW[ i ] : 为i或i的子树能够追溯到的最早的栈中节点的次序号

      •当DFN[ i ]==LOW[ i ]时,为i或i的子树可以构成一个强连通分量

    • 桥与割点

      •怎么判断一个点到父亲的边是桥?

      ​ Low[x]>=dfn[x]

      •怎么判断一个点是割点?

      ​ x存在某个儿子y,low[y]>=dfn[x]

    P1 矿场搭建

    经典题

    题解略

  • 相关阅读:
    如何向线程传递参数
    IntelliJ IDEA 13 Keygen
    单链表的基本操作
    顺序表静态查找
    有向图的十字链表表存储表示
    BF-KMP 算法
    图的邻接表存储表示(C)
    二叉树的基本操作(C)
    VC远控(三)磁盘显示
    Android 数独游戏 记录
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9402460.html
Copyright © 2011-2022 走看看