首页 > 其他分享 >最短路(DJsktra,spfa,flyd).md

最短路(DJsktra,spfa,flyd).md

时间:2024-08-16 22:17:10浏览次数:8  
标签:src head DJsktra val int flyd spfa dist include

最短路

弗洛伊德:全源最短路:

\[\Large DP方程:\\ dp[i][j] = min(dp[i] [j],dp[i][k]+dp[k] [j]) \]

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#define int long long
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 

const int INF = 1e18; // Use a large value suitable for long long
const int N = 505;    // Define N according to problem constraints

using namespace std;

int n, m,src;
int dp[N][N];

void bd() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            dp[i][j] = INF,dp[i][i]=0; // Initialize self-loops to 0

            
    for (int i = 1; i <= m; ++i) {
        int u, v, val;
        cin >> u >> v >> val;
        dp[u][v] = val;
        dp[v][u] = val; // Assuming undirected graph
    }
}

void flyd() {
    for (int i = 1; i <= n; ++i) {
        for (int k = 1; k <= n; ++k) {
            for (int j = 1; j <= n; ++j) {
                if (dp[i][k] != INF && dp[k][j] != INF) {
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
    }
}

bool check() {
    //检查负环
    int src=1;
    for (int i = 1; i <= n; ++i) {
        if (dp[src][i] < 0) 
            return true; // Negative cycle detected
    }
    return false;
}

signed main() {
    ios;
    bd();
    flyd();
    
    if (check()) 
        cout << "Negative cycle";
    else 
        cout << "No negative cycle" << endl;
    
    return 0;
}

2.Bellman-fold

#include <cstdio>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define ep emplace_back 

#define int long long 
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 
const int N = 2e5+9;
const int inf2 = 0x7f7f7f7f; //2139062143 memset赋值用

using namespace std;


int n, m, src;
struct node {
    int to, val, next;
};
node e[N];
int head[N], idx = 0;
int dist[N];
bool vis[N];  // Added vis array
queue<int> q;

void add(int u, int v, int val) {
    e[idx] = {v, val, head[u]};
    head[u] = idx++;
}

void bd() {
    cin >> n >> m >> src;
    memset(head, -1, sizeof(head));
    memset(dist,inf2,sizeof dist);
    for(int i = 1; i <= m; ++i) {  // Changed from N to m
        int u, v, val;
        cin >> u >> v >> val;
        add(u, v, val);
    }
}
void bellman_Ford(){
    dist[src]=0;
    for(int i=1;i<=n-1;++i){
        for(int u=1;u<=n;++u){
            for(int j=head[u] ; ~j ; j=e[j].next){
                int v = e[j].to;
                int val = e[j].val;
                if(dist[v] > dist[u] + val){
                    dist[v] = dist[u]+val;
                }
            }
        }
    }
}
bool check(){
    for(int u=1 ; u<=n ; ++u){
        for(int i =head[u] ; i!=-1 ; i=e[i].next){
            int v =e[i].to;
            int val = e[i].val;
            if(dist[v] > dist[u] + val){
                return true;
               //存在负权环 
            }
        }
    }
    return false;
}
signed main(){
    ios;
    bd();
    bellman_Ford();
    for(int i=1 ; i<=n ;++i) cout<<dist[i]<<" ";
    return 0;
}

3.spfa

#include <cstdio>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 
using namespace std;

#define INF 0x7f7f7f7f
const int N = 2e6 + 9;

int n, m, src;
struct node {
    int to, val, next;
};
node e[N];
int head[N], idx = 0;
int dist[N];
bool vis[N];  // Added vis array
queue<int> q;

void add(int u, int v, int val) {
    e[idx] = {v, val, head[u]};
    head[u] = idx++;
}

void bd() {
    cin >> n >> m >> src;
    memset(head, -1, sizeof(head));
    memset(dist,INF,sizeof dist);
    for(int i = 1; i <= m; ++i) {  // Changed from N to m
        int u, v, val;
        cin >> u >> v >> val;
        add(u, v, val);
    }
}

void spfa() {
    dist[src] = 0;
    q.push(src);
    vis[src] = true;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for (int i = head[u]; i != -1; i = e[i].next) {
            int v = e[i].to;
            int val = e[i].val;
            if (dist[u] + val < dist[v]) {
                dist[v] = dist[u] + val;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
}
bool check(){
    
}
void print() {
    for (int i = 1; i <= n; ++i) {
        cout << dist[i] << " ";
    }
    cout << endl;  // Optionally add a newline at the end of the output
}

signed main() {
    ios;
    bd();
    spfa();
    print();  // Call the print function to display results
    return 0;  // Add return statement for main
}

4.Djstra

朴素版

#include <cstdio>
#include <queue>
#include <deque>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>

#define int long long 
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 
const int N = 2e6+9;
const int inf2 = 0x7f7f7f7f; //2139062143 memset赋值用

using namespace std;

int n,m,src;
int head[N],idx=0;
int dist[N];
bool vis[N];
struct node{
    int to,val,next;
}e[N<<1];
void add(int u,int v,int val){
    e[idx] = {v,val,head[u]};
    head[u] = idx++;
}
void bd(){
    cin>>n>>m>>src;
    memset(head,-1,sizeof head);
    memset(dist,inf2,sizeof dist);
    for(int i=1; i<=m; ++i){
        int u,v,val;
        cin>>u>>v>>val;
        add(u,v,val);
    }
}
void dj(){
    dist[src]=0;
    for (int i = 1; i <= n; ++i) {
        int u = -1;
        for (int j = 1; j <= n; ++j) {
            if (!vis[j] && (u == -1 || dist[j] < dist[u])) {
                u = j;
            }
        }
        
        if (dist[u] == inf2) break;
        vis[u] = true;

        for (int i = head[u]; i != -1; i = e[i].next) {
            int v = e[i].to;
            int value = e[i].val;
            dist[v] = min(dist[v],dist[u]+value);
        }
    }
}
signed main(){
    ios;
    bd();
    dj();
    for(int i=1 ;i<=n ;++i )
            cout<<dist[i]<<" ";

    return 0;
}

二叉堆优化

#include <cstdio>
#include <queue>
#include <deque>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>

#define int long long 
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 
const int N = 2e6+9;
const int inf2 = 0x7f7f7f7f; //2139062143 memset赋值用

using namespace std;

int n,m,src;
int head[N],idx=0;
int dist[N];
bool vis[N];
struct node{
    int to,val,next;
}e[N<<1];
void add(int u,int v,int val){
    e[idx] = {v,val,head[u]};
    head[u] = idx++;
}
struct edge{
    long long  u,dis;
};
bool operator <(edge a,edge b){
    return a.dis>b.dis;
}
priority_queue<edge>pq;
void bd(){
    cin>>n>>m>>src;
    memset(head,-1,sizeof head);
    memset(dist,inf2,sizeof dist);
    for(int i=1; i<=m; ++i){
        int u,v,val;
        cin>>u>>v>>val;
        add(u,v,val);
    }
}
void dj(){
    dist[src]=0;
    pq.push({src,dist[src]});
    while(pq.size()){
        int u = pq.top().u;
        pq.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u] ; i!=-1 ;i=e[i].next){
            int v = e[i].to;
            int val = e[i].val;
            if(dist[v] > dist[u] + val){
                dist[v] = dist[u] + val;
                pq.push(edge{v,dist[v]});
            }
        }
    }
}
signed main(){
    ios;
    bd();
    dj();
    for(int i=1 ;i<=n ;++i ) cout<<dist[i]<<" ";
    return 0;
}

标签:src,head,DJsktra,val,int,flyd,spfa,dist,include
From: https://www.cnblogs.com/Phrink734/p/18363743

相关文章

  • 算法板子:最短路问题——包含朴素Dijkstra算法、堆优化版的Dijkstra算法、SPFA算法、Fl
    目录1.几种算法的用途2.Dijkstra算法——求源点到其他所有点的最短路径(不能处理负边权)(1)朴素Dijkstra算法——适用于稠密图(2)堆优化版的Dijkstra算法——适用于稀疏图4.SPFA算法——求源点到其他所有点的最短路径、判断是否存在负环(可以处理负边权)(1)求有负边权的图......
  • 代码随想录算法训练营第63天 | SPFA算法优化+变式
    94.城市间货物运输Ihttps://kamacoder.com/problempage.php?pid=1152Bellman_ford队列优化算法(又名SPFA)https://www.programmercarl.com/kamacoder/0094.城市间货物运输I-SPFA.html95.城市间货物运输IIhttps://kamacoder.com/problempage.php?pid=1153bellman_ford之判......
  • 图的最短路径算法(SPFA,Dijkstra,Bellman_Ford)(迪杰斯特拉算法,Spfa算法,贝尔曼-福特算
    目录Dijkstra迪杰斯特拉算法写法时间复杂度例题描述输入描述输出描述样例输入用例输出用例写法Spfa算法例题描述输入描述输出描述样例输入用例输出用例写法Bellman_Ford算法(贝尔曼-福特算法)写法例题描述输入描述输出描述样例输入样例输出样例......
  • 代码随想录算法训练营第六十六天 | Bellman_ford 队列优化算法(SPFA)、Bellman_ford之
    Bellman_ford队列优化算法(SPFA)题目链接:https://kamacoder.com/problempage.php?pid=1152文档讲解:https://programmercarl.com/kamacoder/0094.%E5%9F%8E%E5%B8%82%E9%97%B4%E8%B4%A7%E7%89%A9%E8%BF%90%E8%BE%93I-SPFA.html思路Bellman_ford算法每次松弛都是对所......
  • SPFA算法模板和判断负环
    851.spfa求最短路-AcWing题库852.spfa判断负环-AcWing题库#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;intn,m,k;inth[N],e[N],idx,w[N],ne[N];intq[N],tt=-1,hh=0;voidadd(inta,intb,intc){ e[idx]=b; ne[idx]=h[a]; w[idx]=c;......
  • SPFA 判负环
    SPFA判负环大家好,我是Weekoder!今天我要讲的是接上一次SPFA最短路算法衍生而来的一个应用——判断图中是否存在负环。我将介绍两种判负环的方法,都基于SPFA。负环的概念负环是什么?负环就是在图中的一个环,其边权之和为负数。如下图:可以看到,这个环的权值和是\((-2)+(-1)+1......
  • 最短路算法之:SPFA 算法
    最短路系列:SPFA算法大家好,我是Weekoder!终于,我们的最短路算法SPFA闪亮登场了!虽然话是这么说,但是我还是建议大家先学习Dijkstra算法,再来学习SPFA。并且我们在这里学习的SPFA算法只能通过P3371,并不能通过标准版的P4779。SPFA的原型——Bellman-Ford在学习SPFA之前,我......
  • 图论-SPFA与差分约束
    闻道有先后,术业有专攻当用来判断负环的时候,SPFA还挺好用的intpre[N];voidprint_path(ints,intt){if(s==t){cout<<s;return;}print_path(s,pre[t]);cout<<""<<t;}inthead[N],cnt;structEdge{intfrom,to,nxt,c;}e[......
  • 套利(spfa判环+STL)
    套利题目描述套利是利用汇率差异实现货币增值。例如,1美元可以兑换0.5英镑、1英镑可以兑换10法郎、1法郎可以兑换0.21美元。接下来,一个聪明的交易商就可以从1美元开始,0.5*10.0*0.21=1.05美元,获得了5%的利润。你的任务是写一个程序,从输入文件读入汇率清单,然后决定套利......
  • [USACO06DEC] Wormholes G(spfa判断环)
    [USACO06DEC]WormholesG题目背景英文题面见此链接题目描述John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有m......