图论-Bellman-Ford算法

大致的算法:

struct Node{
    int v,dis;
};
vector<Node>Adj[MAXV];
int n,d[MAXV];
bool Bellman(int s)
{
    fill(b,b+MAXV,INF);
    d[s]=0;
    for(int i=0;i<n-1;i++)
    {
        for(int u=0;u<n;u++)
        {
            for(int j=0;j<Adj[u].size();j++)
            {
                int v=Adj[u][j].v , dis = Adj[u][j].dis;
                if(d[u]+dis<d[v])
                {
                    d[v]=d[u]+dis;    //松弛操作 
                } 
            }
        }
    }
    //判断是否有负环的代码 
    for(int u=0;u<n;u++)
    {
        for(int j=0;j<Adj[u].size();j++)
        {
            int v=Adj[u][j].v , dis = Adj[u][j].dis;
            if(d[u]+dis<d[v])
            {
                //d[v]=d[u]+dis;松弛操作
                return false; 
            } 
        }
    }
    return true;
}

实例:一般正常的没有源点可达的负环

因此判断负环的过程可以省略。

#include<cstdio>
#include<vector>
#include<set>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXV = 1000;
const int INF = 0xFFFFFFF;
struct Node{
    int v,dis;;
    Node(int _v,int _dis){ v=_v ; dis=_dis; }
};
vector<Node>Adj[MAXV];
int n,m,st,ed,weight[MAXV];
int d[MAXV],w[MAXV],num[MAXV];
set<int>pre[MAXV];
//使用邻接表实现,因为邻接矩阵的复杂度达到O(V^3),而邻接表只有O(VE) 
bool Bellman(int s)
{
    fill(d,d+MAXV,INF);
    memset(w,0,sizeof(w));
    memset(num,0,sizeof(num));
    d[s]=0;
    w[s]=weight[s];
    num[s]=1;
    for(int i=0;i<n-1;i++) //n-1操作 
    {
        for(int u=0;u<n;u++)
        {
            for(int j=0;j<Adj[u].size();j++)
            {
                int v=Adj[u][j].v;
                int dis=Adj[u][j].dis;
                if(d[u]+dis<d[v])
                {
                    d[v]=d[u]+dis;
                    num[v]=num[u];
                    w[v]=w[u]+weight[v];
                    pre[v].clear();
                    pre[v].insert(u);    
                }
                else if(d[u]+dis==d[v])
                {
                    if(w[u]+weight[v]>w[v])
                    {
                        w[v]=w[u]+weight[v];
                    }
                    pre[v].insert(u);
                    num[v]=0;
                    set<int>::iterator it;
                    for(it=pre[v].begin();it!=pre[v].end();it++) num[v]+=num[*it];
                }    
            }    
        }    
    } 
    /*
    省略了判断是否存在负环的操作
    for(int u=0;u<n;u++)
    {
        for(int j=0;j<Adj[u].size();j++)
        {
            int v=Adj[u][j].v;
            int dis=Adj[u][j].dis;
            if(d[u]+dis<d[v])
            {
                return false;
            }                
        }    
    }    
    */
    return true; 
}
int main(void)
{
    scanf("%d%d%d%d",&n,&m,&st,&ed);
    for(int i=0;i<n;i++) scanf("%d",&weight[i]);
    int u,v,wt;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&u,&v,&wt);
        Adj[u].push_back(Node(v,wt));
        Adj[v].push_back(Node(u,wt)); 
    }
    Bellman(st);
    printf("%d %d\n",num[ed],w[ed]);
    return 0;    
} 

 

posted @ 2018-04-15 13:05  最美遇见你  阅读(180)  评论(0)    收藏  举报