1. 程式人生 > >題解 P3371 【模板】單源最短路徑(弱化版)

題解 P3371 【模板】單源最短路徑(弱化版)

一個story:

2018.10.3,晚上,在與我校是競爭關係的學校的機房(去一起集訓)訓練。

我:(頹)

對方教練:(走過來)

我:(趕快開始假裝研究SPFA)

對方教練:這是?最短路?

我:是啊是啊(瘋狂掩飾尷尬)

對方:這是SPFA?

我:是啊是啊(瘋狂掩飾尷尬)

對方:嗯,為什麼不寫dijstra?

我:因為.嗯…這個,因為…SPFA好寫!(霧)

對方:dijkstra也很好寫啊

我:這個…因為…SPFA好用啊,啊呵呵呵呵~~~~

對方:嗯?可是它會被卡啊,我從來只寫dijkstra。

我:啊哈哈或或哈哈哈,好吧

於是我研究了一下dijkstra,哦哦哦,除了不能處理負權,還是很好用的,教練沒有坑我!

在這裡發一下STL堆優化的dijkstra,因為用負值處理,所以甚至不用寫比較函式,程式碼自然比一般STL還要簡潔,666

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<stack>
#include<set>
#include<map>
#include<cmath>
#include<list>
#include<cstring>
#include <climits>//bei
using namespace std;
priority_queue< pair<int,int> > q;
long long cnt=0,dis[1000000],vis[1000000],hand[1000000],n,m,g;
struct aa//靜態鄰接表,好寫又不佔太多空間,抱走了
{
    int to,next,w;
};
aa xx[10000000];
inline void djstl()
{
    for(int i=1;i<=n;i++)
      dis[i]=2147483647;
    q.push(make_pair(0,g));dis[g]=0;
    while(!q.empty())
    {
        int now=q.top().second;
        q.pop();
        if(vis[now]==1) continue;
        vis[now]=1;
        for(int i=hand[now];i;i=xx[i].next)
        {
            int v=xx[i].to;
            if(dis[v]>dis[now]+xx[i].w)
            {
                dis[v]=dis[now]+xx[i].w;
                q.push(make_pair(-dis[v],v));
            }
        }
    }

}
int main()
{
    cin>>n>>m>>g;
    for(int i=1;i<=m;i++)//處理邊,讀入靜態鄰接表
    {
        int a,b,c;
        cin>>a>>b>>c;
        xx[++cnt].to=b;
        xx[cnt].next=hand[a];//存的是上一條邊
        xx[cnt].w=c;
        hand[a]=cnt;
    }
    djstl();
    for(int i=1;i<=n;i++)
    {
        if(g==i) cout<<0<<" ";
        else cout<<dis[i]<<" ";
    }
    cout<<endl;
    return 0;
}