zoukankan      html  css  js  c++  java
  • 带负边权的最短路径(有向图)——Bellman-Ford算法

    参考了一位大佬的代码,一直很喜欢简洁的代码。(来源及出处已附上)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    #define MAX 100
    #define INF 0x3f3f3f
    using namespace std;
    //有向图
    struct Edge
    {
        int u,v,cost;
    }e[MAX];
    int dist[MAX];  //最短路径
    int prev[MAX];  //路径
    int m,n;    //边数和顶点数
    
    bool Bellman_Ford(int v0)
    {
        int u=v0;
        for(int i=1;i<=n;i++)
            dist[i]=INF;
        dist[u]=0;
        for(int i=1;i<=n;i++)
            for(int j=0;j<m;j++)
                if(dist[e[j].v]>dist[e[j].u]+e[j].cost)
                {
                    dist[e[j].v]=dist[e[j].u]+e[j].cost;
                    prev[e[j].v]=e[j].u;
                }
        for(int i=0;i<m;i++)
            if(dist[e[i].v]>dist[e[i].u]+e[i].cost)
                return 0;
        return 1;
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<m;i++)
            cin>>e[i].u>>e[i].v>>e[i].cost;
        if(Bellman_Ford(1))
            for(int i = 1; i <= n; ++i) //每个点最短路
            {
                printf("%d
    ", dist[i]);
            }
        else
            printf("have negative circle
    ");
        return 0;
    }
    ————————————————
    版权声明:本文为CSDN博主「weixin_43249938」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_43249938/article/details/88217729

    例题:

    The Preliminary Contest for ICPC Asia Nanjing 2019  H. Holy Grail

    As the current heir of a wizarding family with a long history,unfortunately, you find yourself forced to participate in the cruel Holy Grail War which has a reincarnation of sixty years.However,fortunately,you summoned a Caster Servant with a powerful Noble Phantasm.When your servant launch her Noble Phantasm,it will construct a magic field,which is actually a directed graph consisting of n vertices and m edges.More specifically,the graph satisfies the following restrictions :
    
    
    Does not have multiple edges(for each pair of vertices x and y, there is at most one edge between this pair of vertices in the graph) and does not have self-loops(edges connecting the vertex with itself).
     May have negative-weighted edges.
     Does not have a negative-weighted loop.
     n<=300 , m<=500.
    Currently,as your servant's Master,as long as you add extra 6 edges to the graph,you will beat the other 6 masters to win the Holy Grail.
    
    
    However,you are subject to the following restrictions when you add the edges to the graph:
    
    
    Each time you add an edge whose cost is c,it will cost you c units of Magic Value.Therefore,you need to add an edge which has the lowest weight(it's probably that you need to add an edge which has a negative weight).
     Each time you add an edge to the graph,the graph must not have negative loops,otherwise you will be engulfed by the Holy Grail you summon.

    Input
    Input data contains multiple test cases. The first line of input contains integer t — the number of testcases (1≤t≤5).
    For each test case,the first line contains two integers n,m,the number of vertices in the graph, the initial number of edges in the graph.
    Then m lines follow, each line contains three integers x, y and w (0≤x,y<n,-10^9≤w≤10^9, x�​=y) denoting an edge from vertices x to y (0-indexed) of weight w.
    Then 6 lines follow, each line contains two integers s,t denoting the starting vertex and the ending vertex of the edge you need to add to the graph.
    It is guaranteed that there is not an edge starting from s to t before you add any edges and there must exists such an edge which has the lowest weight and satisfies the above restrictions, meaning the solution absolutely exists for each query.
     
    Output
    For each test case,output 666 lines.
    Each line contains the weight of the edge you add to the graph.

    
    
    样例输入:
    1
    10 15
    4 7 10
    7 6 3
    5 3 3
    1 4 11
    0 6 20
    9 8 25
    3 0 9
    1 2 15
    9 0 27
    5 2 0
    7 3 -5
    1 7 21
    5 0 1
    9 3 16
    1 8 4
    4 1
    0 3
    6 9
    2 1
    8 7
    0 4
    样例输出:
    -11
    -9
    -45
    -15
    17
    7

    AC代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 #define MAX 900
     6 #define INF 0x3f3f3f
     7 using namespace std;
     8 struct Edge
     9 {
    10     int u,v,cost;
    11 }e[MAX];
    12 int dist[MAX];  //最短路径
    13 int m,n;    //边数和顶点数
    14 
    15 bool Bellman_Ford(int v0)
    16 {
    17     int u=v0;
    18     for(int i=1;i<=n;i++)
    19         dist[i]=INF;
    20     dist[u]=0;
    21     for(int i=1;i<=n;i++)
    22         for(int j=0;j<m;j++)
    23             if(dist[e[j].v]>dist[e[j].u]+e[j].cost)
    24             {
    25                 dist[e[j].v]=dist[e[j].u]+e[j].cost;
    26             }
    27     for(int i=0;i<m;i++)
    28         if(dist[e[i].v]>dist[e[i].u]+e[i].cost)
    29             return 0;
    30     return 1;
    31 }
    32 
    33 int main()
    34 {    int T;
    35     cin >> T; 
    36     while(T--){
    37         cin>>n>>m;
    38         for(int i=0;i<m;i++){
    39             int a,b,c;
    40             cin >> a >> b >> c;
    41             e[i].u = a+1;
    42             e[i].v = b+1;
    43             e[i].cost = c;
    44         }
    45         for(int i = 0 ; i < 6; i++){
    46             int t1, t2;
    47             cin >> t1 >> t2;
    48             t1++;
    49             t2++;
    50             Bellman_Ford(t2);
    51             int res = -dist[t1];
    52             cout << res << endl;
    53             e[m].u = t1;
    54             e[m].v = t2;
    55             e[m].cost = res;
    56             m++;
    57         }
    58        
    59     }
    60     
    61 
    62     return 0;
    63 }
  • 相关阅读:
    vue keep-alive的使用
    vscode 快捷键整理
    form表单的验证validator如何传递参数
    使用elementui 的validateField,resetFields,clearValidate的使用
    vue sass样式穿透实现
    部署node服务(在本地模拟环境进行部署)
    利用存css实现弧形边界
    koa mongoose 实践篇,各种必要的功能总结;
    koa mogoose 创建后台服务连接数据库并进行增删改查
    vue项目中 render函数直接操作html元素报错
  • 原文地址:https://www.cnblogs.com/xyishere/p/11442751.html
Copyright © 2011-2022 走看看