最短路——SPFA

來源:互聯網
上載者:User

bellman演算法有太多冗餘的鬆弛操作,SPFA利用隊列省去了冗餘的討論,時間複雜度約為O(KE)k約為2,E為邊數。

代碼如下:

#include<cstdio>#include<iostream>#include<queue>const int  inf=10000000;using namespace std;queue<int>q;int n,m,x,y,map[105][105],vis[105],dist[105];    // vis[i]記錄i是否在隊列中;void input(){int p,q,i,j,t;scanf("%d%d",&n,&m);for(i=1;i<=n;i++) for(j=1;j<=n;j++)   if(i!=j)map[i][j]=inf;for(i=1;i<=m;i++){scanf("%d%d%d",&p,&q,&t);map[p][q]=t;} scanf("%d%d",&x,&y);}void SPFA(){int i,j;for(i=1;i<=n;i++)dist[i]=inf;    //初始化dist[x]=0;q.push(x);vis[x]=true;while(!q.empty()){int cur=q.front();    //取隊首元素q.pop();vis[cur]=false;      //及時修正標記for(i=1;i<=n;i++)if(dist[cur]+map[cur][i]<dist[i]){dist[i]=dist[cur]+map[cur][i];if(!vis[i]){vis[i]=true;q.push(i);}}} printf("%d",dist[y]);}int main(){input();SPFA();} 


根據演算法原理,每個點最多隻會入隊n次,如過某個點入隊達到n+1(這是血的教訓)次,那麼該圖中有負權迴路。

以下是利用邊儲存的結構體形式的SPFA,並且帶有負權迴路判定的代碼

last[x] 表示以x為起點的最後一條邊

next[x]表示和x邊同起點的下一條邊,0表示沒有了

edge是儲存邊的數組

<pre name="code" class="cpp">#include<cstdio>    #include<iostream>  #include<cstring>    #include<queue>    #include<vector>       #define LL long long    #define CLEAR(XXX) memset((XXX),0,sizeof(XXX))  using namespace std;      const LL inf=1000000000000LL;    const int maxn=1005,maxm=100005;        inline void _read(int &x){        char ch=getchar(); bool mark=false;        for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;        for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';        if(mark)x=-x;    }    struct Edge{        int from,to,w;        Edge(int from,int to,int w):from(from),to(to),w(w){}  };      struct SPFA{        int  n,m;        vector<Edge> edge;        int last[maxm],Next[maxm];        LL dist[maxn];        int cnt[maxn];        bool vis[maxn];        void init(int n){            this->n = n;            m=0;            CLEAR(last);  CLEAR(Next);            edge.clear();            edge.push_back(Edge(0,0,0));        }        void add_edge(int from,int to,int dist){            edge.push_back(Edge(from,to,dist));            m=edge.size()-1;            Next[m]=last[from];            last[from]=m;        }        bool solve(int s){            int i;            CLEAR(vis); CLEAR(cnt);              for(i=1;i<=n;i++) dist[i]=inf;            dist[s]=0;          vis[s]=true;cnt[s]++;            queue <int> q;            q.push(s);            while(!q.empty()){                int x=q.front();                q.pop();vis[x]=false;  //及時修改標記               for(i=last[x];i;i=Next[i]){                    Edge& e=edge[i];                    if(dist[e.from]+e.w<dist[e.to]){                        dist[e.to]=dist[e.from]+e.w;                        if(!vis[e.to]){                            cnt[e.to]++;  //統計入隊次數,判斷負權迴路                           if(cnt[e.to]==n+1)return false;                            q.push(e.to) ;                            vis[e.to]=true;                        }                    }                 }            }            return true;        }        void answer(){            for(int i=1;i<=n;i++)                if(dist[i]>=inf)printf("NoPath\n");                else printf("%I64d\n",dist[i]);        }    };     int main(){        SPFA spfa;        int n,m,s,i,from,to,dist;        _read(n);_read(m);_read(s);        spfa.init(n);         for(i=1;i<=m;i++){            _read(from);_read(to);_read(dist);            spfa.add_edge(from,to,dist);        }        if(spfa.solve(s))spfa.answer();        else printf("negetive loop");       return 0;   }    


 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.