Bellman-Ford模板

来源:互联网 发布:关联规则挖掘算法程序 编辑:程序博客网 时间:2024/05/22 14:44
/*单源最短路bellman_ford算法,复杂度O(VE)可以处理负边权图。可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路先初始化,然后加入所有边点的编号从1开始(从0开始简单修改就可以了)*/#include<iostream>#include<cstdio>#include<vector>#include<cstring>#include<fstream>using namespace std;const int INF=0x3f3f3f3f;const int MAXN=550;const int MAXM=1e3+5;int dist[MAXN],head[MAXN],tot;struct Edge{    int from,to,cost,nxt;    Edge(int _from=0,int _to=0,int _cost=0):from(_from),to(_to),cost(_cost){}}e[MAXM];void addedge(int u,int v,int w){    e[tot].from=u;e[tot].to=v;e[tot].cost=w;    e[tot].nxt=head[u];head[u]=tot++;}bool bellman_ford(int st,int n)//点的编号从1开始{    for(int i=1;i<=n;i++) dist[i]=INF;    dist[st]=0;    bool flag;    for(int i=1;i<n;i++)    {        flag=false;        for(int j=0;j<tot;j++)        {            int u=e[j].from,v=e[j].to,cost=e[j].cost;            if(dist[v]>dist[u]+cost)            {                dist[v]=dist[u]+cost;                flag=true;            }        }        if(!flag) return true;//没有负环回路    }    for(int j=0;j<tot;j++)        if(dist[e[j].to]>dist[e[j].from]+e[j].cost) return false;//有负环回路    return true;//没有负环回路}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(head,-1,sizeof(head));        tot=0;        int u,v,c;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&c);            //u++,v++;            addedge(u,v,c);            addedge(v,u,c);        }        int st,ed;        scanf("%d%d",&st,&ed);        //st++,ed++;        bool mark=bellman_ford(st,n);        if(dist[ed]!=INF) printf("%d\n",dist[ed]);        else printf("-1\n");        if(mark)        {            printf("no negative circle\n");            for(int i=1;i<=n;i++) printf("%d ",dist[i]);            printf("\n");        }        else printf("have negative circle\n");    }    return 0;}
原创粉丝点击