图论-最短路个人总结

图论-最短路个人总结

差分约束

如若一个系统由n个变量和m个不等式组成,并且这m个不等式对应的系数矩阵中每一行有且仅有一个1和-1,其它的都为0,这样的系统称为差分约束( difference constraints )系统
对 于 形 如 : B − A &lt; = c ⋯ ( 1 ) C − B &lt; = a ⋯ ( 2 ) C − A &lt; = b ⋯ ( 3 ) 对于形如:\\ B-A&lt;=c\cdots (1)\\ C-B&lt;=a\cdots (2)\\ C-A&lt;=b\cdots (3)\\ BA<=c(1)CB<=a(2)CA<=b(3)
我们要知道 C − A C-A CA的最大值,即 C − A &lt; = T C-A&lt;=T CA<=T T T T的值。通过 ( 1 ) + ( 2 ) (1)+(2) (1)+(2),可以得到 C − A &lt; = a + c C-A&lt;=a+c CA<=a+c,所以这个问题就是求。对于 B − A &lt; = c B-A&lt;=c BA<=c 来说,等价于 B &lt; = c + A B&lt;=c+A B<=c+A,类似于求最短路中的松弛操作if(dis[u]+w<dis[v]) dis[v]=dis[u]+w,松弛操作的目的就是尽可能使dis[u]+w>=dis[v],所以求 T ​ T​ T的值就是求A~>B,B~>C,A~>C,所形成的有向图中A~>C的最短路径
在这里插入图片描述
相反的若形如以下:
对 于 形 如 : B − A &gt; = c ⋯ ( 1 ) C − B &gt; = a ⋯ ( 2 ) C − A &gt; = b ⋯ ( 3 ) 对于形如:\\ B-A&gt;=c\cdots (1)\\ C-B&gt;=a\cdots (2)\\ C-A&gt;=b\cdots (3)\\ BA>=c(1)CB>=a(2)CA>=b(3)
并求 C − A C-A CA的最小值,即 C − A &gt; = T C-A&gt;=T CA>=T T T T的值,也就是求上图中C~>A的最长路径。
若有形如 A − B = c A-B=c AB=c的等式,可以转化为 c &lt; = A − B &lt; = c c&lt;=A-B&lt;=c c<=AB<=c,即 A − B &lt; = c , B − A &lt; = − c A-B&lt;=c,B-A&lt;=-c AB<=c,BA<=c
若是整数规划,且有形如 A − B &lt; c A-B&lt;c AB<c,可以转化为 A − B &lt; c − 1 A-B&lt;c-1 AB<c1

Dijkstra算法

void Dijkstra(int n,int r){
    memset(dis,INF,sizeof(dis));dis[r]=0;
    priority_queue<node>q;
    q.push(node(r,0)); 
    while(!q.empty()){
        node now=q.top();q.pop();
        int &u=now.v;
        if(vis[u]) continue;vis[u]=1;
        for(int i=head[u];~i;i=g[i].next){
            int &v=g[i].v,&w=g[i].w;
            if(!vis[v]&&dis[u]+w<dis[v]){
                dis[v]=dis[u]+w;
                q.push(node(v,dis[v]));
            }
        }
    }
}

SPFA算法

bool SPFA(int n,int r){
    memset(dis,INF,sizeof(dis));dis[r]=0;
    memset(vis,0,sizeof(vis));vis[r]=1;
    memset(ccnt,0,sizeof(ccnt));ccnt[r]=1;
    queue<int>q;q.push(r);
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(int i=head[u];~i;i=g[i].next){
            int &v=g[i].v,&w=g[i].w;
            if(dis[u]+w<dis[v]){
                dis[v]=dis[u]+w;
                if(!vis[v]){
                    q.push(v);vis[v]=1;
                    if(++ccnt[v]>n) return 1;
                }
            }
        }
    }
    return 0;
}

Bellman_ford算法

bool Bellman_ford(int n,int r){
    memset(dis,0,sizeof(dis));dis[r]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<cnt;j++){
            int &u=g[j].u,&v=g[j].v,&w=g[j].w;
            if(dis[u]+w<dis[v]){
                if(i==n) return 1;
                dis[v]=dis[u]+w;
            }
        }
    }
    return 0;
}

Floyd算法

for(int k=1;k<=n;k++){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][k]&&a[k][j]) a[i][j]=1;  //传递闭包
        }
    }
}

for(int k=1;k<=n;k++){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][k]+a[k][j]<a[i][j]) a[i][j]=a[i][k]+a[k][j];  //任意两点最短路
        }
    }
}

Others

  • 对于最短路,若有负环存在,则起始点与此环相连的所有点的最短路为无穷小。可通过dfs标记所有无穷小的点。
  • 相反对于最长路类似。
  • 对于有向图,求其他所有点到1号点的最短路径。即将原图建立反向图,再对1号点求单源最短路。
  • 若求一条1~n的路径,使得这条路径中的最小长度的边长度最大,即将求最长路的松弛操作改为 min(dis[u],w)>dis[v]
  • 同理,求一条1~n的路径,使得这条路径中的最长的边的长度最小,即将求最短路的松弛操作改为 max(dis[u],w)<dis[v]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值