算法导论24(单源最短路径)

1.Bellman-Ford算法

#include<iostream>    
using namespace std;
  
const int N=100;   
int d[N],pred[N];

struct Node
{
    int v,w;
    Node *next;
};

struct Graph    
{       
    int VNum,ENum;
    Node Adj[N];    
};    

void createGraph(Graph &G)    
{    
    cin>>G.VNum>>G.ENum;   
    for(int i=0;i<G.VNum;++i)G.Adj[i].next=0;
    int u,v,w;    
    for(int i=0;i<G.ENum;++i)    
    {    
        cin>>u>>v>>w;    
        Node *p=new Node;  
        p->v=v;
        p->w=w;
        p->next=G.Adj[u].next;  
        G.Adj[u].next=p;
    }    
}          
  
void initializeSingleSource(Graph G,int s)  
{  
    for(int i=0;i<G.VNum;++i)  
    {  
        d[i]=INT_MAX;  
        pred[i]=-1;  
    }  
    d[s]=0;  
}  
  
void relax(int u,int v,int w)  
{  
    if(d[u]+w<d[v])  
    {  
        d[v]=d[u]+w;  
        pred[v]=u;  
    }  
}  
  
bool BellmanFord(Graph G,int s)  
{  
    initializeSingleSource(G,s);
    //对每条边松弛VNum-1次
    for(int i=1;i<G.VNum;++i)  
    {  
        for(int j=0;j<G.VNum;++j)  
        {  
            for(Node *p=G.Adj[j].next;p;p=p->next)relax(j,p->v,p->w);   
        }  
    }  
    for(int j=0;j<G.VNum;++j)  
    {  
        for(Node *p=G.Adj[j].next;p;p=p->next)  
        {  
            if(d[j]+p->w<d[p->v])return false;
        }  
    }  
    return true;  
}  
  
void printPath(Graph G,int s,int v)
{
    if(v==s)cout<<s<<' ';
    else 
    {
        printPath(G,s,pred[v]);
        cout<<v<<' ';
    }
}

//输入
//5 10
//0 1 6
//0 3 7
//1 2 5
//1 3 8
//1 4 -4
//2 1 -2
//3 2 -3
//3 4 9
//4 0 2
//4 2 7
//
//输出
//0 0
//2 0 3 2 1
//4 0 3 2
//7 0 3
//-2 0 3 2 1 4

int main()      
{  
    Graph G;  
    createGraph(G);  
    if(BellmanFord(G,0))  
    { 
        for(int i=0;i<G.VNum;i++)  
        {    
            cout<<d[i]<<' ';
            printPath(G,0,i);
            cout<<endl;
        }  
    }     
    else cout<<"a negative circle exits"<<endl;
    return 0;      
}  


2.Dijkstra算法

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

const int N=100;
int d[N],pred[N];

struct Node
{
    int v,w;
    Node *next;
};

struct Graph 
{ 
    int VNum,ENum;
    Node Adj[N];
};  

void createGraph(Graph &G)  
{    
    cin>>G.VNum>>G.ENum;  
    for(int i=0;i<G.VNum;++i)G.Adj[i].next=0;
    int u,v,w;
    for(int i=0;i<G.ENum;++i)  
    {  
        cin>>u>>v>>w;  
        Node *p=new Node;
        p->v=v;
        p->w=w;
        p->next=G.Adj[u].next;
        G.Adj[u].next=p;
    }  
}  

void initializeSingleSource(Graph G,int s)
{
    for(int i=0;i<G.VNum;++i)
    {
        d[i]=INT_MAX;
        pred[i]=-1;
    }
    d[s]=0;
}

void relax(int u,int v,int w)
{
    if(d[u]+w<d[v])
    {
        d[v]=d[u]+w;
        pred[v]=u;
    }
}

bool cmp(int x,int y)
{
    return d[x]>d[y];
}

void Dijkstra(Graph G,int s)
{
    initializeSingleSource(G,s);
    vector<int> S;
    vector<int> Q;
    for(int i=0;i<G.VNum;++i)Q.push_back(i);
    while(!Q.empty())
    {
        make_heap(Q.begin(),Q.end(),cmp);
        int u=Q[0];
        Q.erase(Q.begin());
        S.push_back(u);
        for(Node *p=G.Adj[u].next;p;p=p->next)relax(u,p->v,p->w);
    }
}

void printPath(Graph G,int s,int v)
{
    if(v==s)cout<<s<<' ';
    else 
    {
        printPath(G,s,pred[v]);
        cout<<v<<' ';
    }
}

//输入
//5 10
//0 1 10
//0 3 5
//1 2 1
//1 3 2
//2 4 4
//3 1 3
//3 2 9
//3 4 2
//4 0 7
//4 2 6
//
//输出
//0 0
//8 0 3 1
//9 0 3 1 2
//5 0 3
//7 0 3 4

int main()    
{    
    Graph G;    
    createGraph(G);
    int s=0;
    Dijkstra(G,s);
    for(int i=0;i<G.VNum;++i) 
    {
        cout<<d[i]<<' '; 
        printPath(G,s,i); 
        cout<<endl;
    }   
    return 0;    
}




 

你可能感兴趣的:(算法导论24(单源最短路径))