• 帝都Day6——图论


    //P2O5呢?

    一、图的存储:

    邻接矩阵;邻接表。

    邻接矩阵:n*n的[][],[i][j]节点有边记1没边0 缺点 空间复杂度O(n^2) 占用内存较大(我为什么要把这些东西写到这里呢???)

    邻接表:把每一个点能直接到达的点存储成链表(反正是一个很奇怪的东西,弄懂了会写了会用了就行)单向边(为啥不叫有向边)和双向边(为啥不叫无向边)的区别是无向边反着存一遍再

    const int N=1005;
    const int M=10050;
    int point[N],to[M],next[M],cc;
    
    void AddEdge(int x,int y)
    {
        cc++;
        to[cc]=y;
        next[cc]=point[x];
        point[x]=cc;
    }
    void find(int x)
    {
        int now=point[x];
        while(now)
        {
            printf("%d
    ",now);
            now=next[now];
        }
    }
    int main()
    {
        
    }    
    

     图的遍历(?)(?)(?)——dfs,bfs

    然后是最小生成树(MST问题)

    铺锐母+客路思卡尔

    客路思卡尔:

    const int N=1050;
    const int M=10050;
    struct Edge
    {
        int a,b,c;
    }edge[M];
    int fa[N];//冰炸鸡
    int n,m;
    int ans=0; int getf(int x) { if(fa[x]!=x)
    fa[x] = getf(fa[x]);
        return fa[x]; } bool cmp(Edge x,Edge y) { return x.c<y.c; } int main() { int i,j; scanf("%d%d",&n,&m); for(i=1;i<=m;i++) scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].c); sort(edge+1,edge+m+1,cmp); for(i=1;i<=n;i++) fa[i]=i; for(i=1;i<=m;i++) { int a=edge[i].a; int b=edge[i].b; a=getf(a); b=getf(b); if(a!=b) { ans+=edge[i].c; f[a]=b; } } printf("%d ",ans); }

     然后是普利姆算法

    首先染黑一个点。找一条边权最小的连接白点和黑点的点,把这个边连接的白点变为黑点,这条边加入MST。重复上述过程直到所有点都被染黑。所得的所有边和点就是MST。(woc我竟然写了段文字)代码:

    (待更)

    迟来的problems

    vijos1190:繁忙的都市

    这道题是最小瓶颈生成树,它的最大边权就是kruskal做出来最大边权(最后一个边权),所以直接用kruskal做就行了

    bzoj1016:最小生成树计数

    用kruskal,如果有边权一样的边,选哪条都试一试

    最短路

    福裸衣的,低阶死特辣,SPFA

    Floyd-Warshall算法

    SPFA(笔记被我吃了!)

    Dijkstra(O(n^2))

    Bellman-Ford O(n*m)一般不用。

    problems(忽略s)

    vijos1754

    然后是:拓扑排序

    代码:

    (待更)

    problems:

    构造排列

    构造一个1~n的排列,有m个限制,每个限制是:a要在b前面

    要求字典序最小

    n,m<=10^5

    problemⅡ

    构造一个1~n的排列,有m个限制,每个限制是:a要在b前面

    要求1尽可能靠前,若仍有多解,要求2尽可能靠前,若仍有多解,要求3尽可能靠前(什么鬼续靠前)

    lydsy4010(bzoj4010)

    从后往前做,每次从所有可选的点中选出一个最大的。woc太巧妙了!!!!

    代码迟早会更新的

    (嗯,这里元素路径还是p)

    afternoon-------------

    强连通分量

    在有向图中,如果a能到b,b能到a,就称ab强连通。

    强连通图:有向图中每一对点都强连通,这个图就是强连通图。

    强连通分量:有向图的极大联通子图,就是强连通分量。

    任何一个有向图,都可以划分成若干个强连通分量,并且这些强连通分量没有交集。

    重点来了!tarjan求 强连通分量

    对图进行dfs,我们定义一个dfn[i] dfn[i]表示第i个节点是第几个被dfs到的

    酱紫,我们每个节点都有个编号了

    然后:low[i]表示他能到达的dfn最小的点的编号

    在写tarjan的时候,我们要开一个栈

    [tarjan code]

    缩点:把一个图的每一个强连通分量变成一个点,变成DAG

    有向无环图(DAG)拓扑排序只有在DAG上才有方案。

    DP的状态之间关系如果用有向图来表示就是有向无环图,所以可以记忆化搜索!!

    (难道所有DP都可以记忆化收索???)

    强连通分量的作用,就是缩点,变成有向无环图,woc厉害了

    victoria的舞会3 vijos1023

    把“能通知到”关系抽象成有向图,然后缩点,求所有入度为0的点

    tarjan+新图去重

    [代码]

    problems:

    bzoj1051

    建图,缩点,设t是出度为0的点的数量(t>0)

    当t>1时,ans=0,因为那两个出度为0的点不能相互到达。

    当t=1是,ans=那个出度为0的点对应的缩点前的点的数量。所有的点都能到那个点,也就是那个强连通分量里的所有的点都能被所有点到达。(这题还是比较H2O的)

    Car的旅行路线 vijos1119(笔记被吃了)

    联合权值 vjijos1906

    30分、60分略,AC:枚举每一个点,枚举中间点。

    寻找道路 vijos 1909

    1.求哪些点与终点联通

    2.求哪些点指向的点都与终点联通

    3.在第二部满足条件的点上bfs最短路(因为权值1)

    货车运输 vijos1843

    最大生成树,只在最大生成树上找(kruskal反着排)

    证明:只用最大生成树是足够的

    设A,B,C三点之间互相有边连接,AB、AC在最大生成树中。设AC>AB或BC,那么AC应该在最大生成树中。所以AC<=AB和BC

    华容道 vijos1846

    程序思路先把空格子移动到要移动的格子(一下简称绿格子)旁边,然后(被吞了)(什么题目,这么难)

    然后是一个树上倍增(被吞了)

    欧拉路径:给出来一个图,把这个图的路径走一个遍。起点终点是同一个点:欧拉回路

    蛤密顿路:把这个图的点走个遍。蛤密顿回路同欧拉回路

    然后一个很奇怪的题,我又吞啦!

    完。

  • 相关阅读:
    什么是单例模式?
    下拉列表(web),用jQuery实现
    PS基础
    C#笔记
    C#基础篇--文件(流)
    C#基础篇03
    今天自学了网页上注册某某时的倒计时设置
    主数据管理的Jill Dyche, Evan Levy六层次模型
    scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)
    OpenWrt mt7620n双SSID实现原理
  • 原文地址:https://www.cnblogs.com/oier/p/7209349.html
Copyright © 2020-2023  润新知