SPFA+前向星优化

作用:源点到i点的最短距离(最*权值)。

算法:本质上是BFS,但利用邻接表来处理点与点之间的关系,处理量更大 ;

前向星是一个数组模拟的头插法链表,再处理上比vector快。

代码

时间复杂度 : O(|V|*|E|) ,最坏情况下

输入 :  N(点的数量)  M(边的数量)  src(源点)

X  Y(边) w(权值)

输出 : dist[i] 源点到各点之间的最短距离

const int MaxN=100010;//边的最大数量
struct node
{
    int next,to,w;
};
node edge[MaxN];
int head[MaxN],cnt;//以上为构造链式前向星时所要用到的工具
 
int vis[MaxN];//验证点是否在队列里
int dist[MaxN];//存储距离
queue<int>Q;
 
void init()//初始化函数
{
    memset(head,-1,sizeof(head));//只能设为-1
    memset(vis,0,sizeof(vis));
    memset(dist,63,sizeof(dist));
    cnt=0;
    while(!Q.empty())   Q.pop();
}
void add(int u,int v,int w)//前向星存表
{
    edge[cnt].w=w;
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
 
 
void SPFA(int x)
{
    Q.push(x);
    dist[x]=0;
    vis[x]=1;
    while(!Q.empty())
    {
        int temp=Q.front();
        Q.pop();
        vis[temp]=0;
        for(int i=head[temp];i!=-1;i=edge[i].next)//链式遍历
        {
            int u=edge[i].to;
            int w=edge[i].w;
            if(dist[u]>dist[temp]+w)
            {
                dist[u]=dist[temp]+w;
                if(!vis[u])
                {
                    Q.push(u);
                    vis[u]=1;
                }
            }
        }
    }
}
int main()
{
    int N,M,src;//节点的个数,边的个数,源点
    while(cin>>N>>M>>src)
    {
        int x,y,z;
        init();//初始化
        for(int i=0; i<M; ++i)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);//链式前向星存储
            //add(y,x,z);//当图为无向图或其他情况时
        }
        SPFA(src);
        for(int i=1;i<=N;++i)//源点到每个点的最短距离
            printf("%d
",dist[i]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/l1l1/p/8884579.html