zoukankan      html  css  js  c++  java
  • 图论

    首先

    (color {red}{SPFA已死,Dijkstra当立!})

    (small{color {gray}{咳}})

    前向星

    struct edge{int to,next,v;}e[N<<1];
    int en,head[N];
    void addedge(int x,int y,int v)
    {
        e[++en]==(edge){y,head[x],v};
        head[x]=en;
    }
    void dfs(int x)
    {
        for(int i=head[x];i;i=e[i].next;
        {
            int y=e[i].to;
            dfs(y);
        }
    }
    

    最短路图

    1.没有负环
    2.是DAG

    bellman-ford

    先将在、所有点的最短距离设为∞,起点为0(和dij一样)
    然后对边集(边!)松弛两端端点
    最后得记得检查一下
    有了SPFA了要什么bellman-ford

    SPFA

    就是bellman-ford的priority_queue优化
    (huge {但是})
    (small {color {grey}{它死了}})

    正经点
    就是在bellman-ford的基础上将遍历所有点改为直接从queue取数

    int dis[N],inq[N];
    void spfa()
    {
        memeset(dis,0x3f,sizeof(dis);
        queue<int> q;
        q.push(1);
        inq[1]=1;
        dis[1]=0;
        while(!q.emptu())
        {
            int x=q.front();
            q.pop();
            inq[x]=0;
            for(int i=head[x];i;i=e[i].next)
            {
                int y=e[i].to;
                if(dis[y]>dis[x]+e[i].v)
                {
                    dis[y]=dis[x]+e[i].v;
                    if(!inq[y])
                    {
                        q.push(y);
                        inq[y]=1;
                    }
                }
            }
        }
    }
    

    把松弛的对比比较的大于号改成小于号就可以求最长路

    • (small {color {white}{但是有了Dijkstra要什么SPFA}})

    Dijkstra

    Dij我之前写过,所以
    点我滚过去_(:з」∠)_

    拓扑排序

    将当前入度最小的(联想到priority_queue)点向其他点探索,然后踢出去,找下一个入度最小的点,继续......
    就这样

    queue<int> q;
    int rd[];//入度
    
    void topsort()
    {
        for(int i=1;i<=n;i++)
            if(rd[i]==0)
                q.push(i);
        while(!q.empty())
        {
            int x=q.front;
            q.pop();
            for(int i=head[x];i;i=e[i].next)
            {
                int y=e[i].to;
                rd[y]--;
                if(rd[y]==0)
                    q.push(y);
            }
        }
    }
    

    Floyd

    经典老算法
    时间复杂度(O(n^3))
    太经典了
    不过第三维可以省掉了

    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
                f[i][j]=min(f[i][j],f[i][j]+f[k][j]);
        }
    }
    

    可以做传递闭包,可以跑得飞快

    负环

    1.负环可以用SPFA来判断($small {SPFA突然又活了})
    不过要把SPFA改成dfs,但是可能会当场T掉(如果出题人很恶心)
    2.或者记录每个点的入队次数,只要有点入队次数大于n那就有负环
    3.还有一个,开一个数组记录当前最短路有几个点,如果大于n,那就存在负环
    在对比之下,1会被卡爆,2比3慢一些,所以用3

    bool spfa()
    {
        queue<int> q;
        memset(dis,0x3f,sizeof(dis));
        memset(cnt,0,sizeof(cnt));
        memset(inq,0,sizeof(inq));
        dis[1]=0;
        q.push(1);
        inq[1]=cnt[1]=1;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            inq[x]=0;
            for(int i=1;i;i=e[i].next)
            {
                int y=e[i].to;
                if(dis[y]>dis[x]+e[i].v)
                {
                    cnt[y]=cnt[x]+1;
                    if(cnt[y]>n)
                        return true;
                    dis[y]=dis[x]+e[i].v;
                    if(!inq[y])
                    {
                        q.push(y);
                        inq[y]=1;
                    }
                }
            }
        }
        return false;
    }
    
  • 相关阅读:
    mybatis中的延迟加载
    MyBatis的mapper
    MyBatis的resultMap
    mybatis入门
    mybatis中的#和$的区别(转)
    操作日志记录
    SpringMVC中的异常处理集锦
    vue.js的package.json相关问题解惑
    git的常用操作指令
    http协议参数详解
  • 原文地址:https://www.cnblogs.com/ComputerEngine/p/11149227.html
Copyright © 2011-2022 走看看