spfa slf优化

/*SPFA算法有两个优化算法 SLF 和 LLL: 
SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j) < dist(i),则将j插入队首,否则插入队尾。 
LLL:Large Label Last 策略,设队首元素为i,每次弹出时进行判断,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出对进行松弛操作。
*/
//小的dis在前 
#include<bits/stdc++.h>
using namespace std;

int n,m,s;//起点终点开头

int u[200005],v[200005],w[200005];
int first[200005],nextt[200005];
int dis[200005];

int k2=0;
void make_edge(int a,int b,int c)
{
    k2++;
    u[k2]=a;
    v[k2]=b;
    w[k2]=c;
    nextt[k2]=first[a];
    first[a]=k2;
}

void clean()
{
    int flag=max(n,m);
    for(int i=1;i<=flag;i++)
    {
        first[i]=-1;
        nextt[i]=-1;
    }
    for(int i=1;i<=n;i++)
    {
        if(i==s) dis[i]=0;
        else dis[i]=1e9;
     } 
}

deque<int> q;
int book[200005];

int main()
{
    cin>>n>>m>>s;
    clean();
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        make_edge(a,b,c);
    }
    q.push_back(s);
    book[s]=1;
    while(!q.empty())
    {
        int now_node=q.front();
        q.pop_front();
        book[now_node]=0;
        
        int k=first[now_node];
        while(k!=-1)
        {
            if(dis[v[k]]>dis[u[k]]+w[k])
            {
                dis[v[k]]=dis[u[k]]+w[k];
                if(book[v[k]]==0)
                {
                    book[v[k]]=1;
                    if(!q.empty()/*记得判空*/&&dis[v[k]]<dis[q.front()])
                    {
                        q.push_front(v[k]);
                    }
                    else q.push_back(v[k]);
                }
            }
            k=nextt[k];
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(i==1) cout<<dis[i];
        else cout<<" "<<dis[i];
    }
    cout<<endl;
    return 0;
} 
 

 

posted @ 2018-11-08 19:40  前排吃瓜  阅读(223)  评论(0编辑  收藏  举报