(模板)hdoj2544(最短路--bellman-ford算法)

题目链接:https://vjudge.net/problem/HDU-2544

题意:给n个点,m条边,求点1到点n的最短路。

思路:

  今天学了下bellman_ford,抄抄模板。dijkstra算法和该算法都是单源最短路径算法,但是dij不能适用含负权边的图。而bellman-ford算法适用于负权边,原理是进行n-1次松弛操作,每次都要对m条边进行松弛,所以算法复杂度是O(mn),比dijkstra要高。如果n-1次操作之后还能进行松弛,说明存在负环。

AC code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn=105;
const int maxm=10005;
const int inf=0x3f3f3f3f;
int n,m,dis[maxn],cnt,loop;

struct node{
    int u,v,w;
}edge[maxm<<1];

void adde(int u,int v,int w){
    edge[++cnt].v=v;
    edge[cnt].u=u;
    edge[cnt].w=w;
}

void bellman_ford(int s){
    for(int i=1;i<=n;++i)
        dis[i]=inf;
    dis[s]=0;
    //n-1次松弛    
    for(int i=1;i<n;++i){
        bool ok=0;
        for(int j=1;j<=cnt;++j){
            int u=edge[j].u,v=edge[j].v,w=edge[j].w;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                ok=1;
            }
        }
        if(!ok) break;
    }
    //loop=1说明存在负环
    for(int i=1;i<=cnt;++i){
        int u=edge[i].u,v=edge[i].v,w=edge[i].w;
        if(dis[v]>dis[u]+w){
            loop=1;
            break;
        }
    }
}

int main(){
    while(scanf("%d%d",&n,&m),n||m){
        cnt=0,loop=0;
        for(int i=1;i<=m;++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            adde(u,v,w);
            adde(v,u,w);
        }
        bellman_ford(1);
        printf("%d\n",dis[n]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/11849901.html
今日推荐