Luogu P3371 【模板】单源最短路径

  最短路的模板题。。。

  SPFA打过一遍。 但今天终于看懂了Dijkstra和堆优化,走一发。

  Dijkstra的思想很简单,每次找到和起点dis最小的点,再将该点到其他有边相连的点的dis更新。重复n次即可。记得判断哪个点用过。

  裸Dijkstra复杂度为O(n^2),但对于10000的数据能跑90分。难以置信!

  CODE

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
inline void read(int &x)
{
    x=0; char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
}
const int INF=2147483647,N=10005,M=500005;
vector <int> a[N],l[N];
int n,m,i,j,dis[N],s,x,y,z;
bool f[N];
int main()
{
    read(n); read(m); read(s);
    for (i=1;i<=m;++i)
    {
        read(x); read(y); read(z);
        a[x].push_back(y); l[x].push_back(z);
    }
    memset(f,true,sizeof(f));
    for (i=1;i<=n;++i)
    dis[i]=INF;
    dis[s]=0;
    for (i=1;i<=n;++i)
    {
        x=y=INF;
        for (j=1;j<=n;++j)
        if (dis[j]<y&&f[j]) y=dis[x=j];
        f[x]=0;
        for (j=0;j<a[x].size();++j)
        dis[a[x][j]]=min(dis[a[x][j]],dis[x]+l[x][j]);
    }
    for (i=1;i<=n;++i)
    printf("%d ",dis[i]);
    return 0;
}
                    

  仔细看找出最小dis值的过程,发现总是取出最小的,果断堆优化。(虽然线段树也可以)

  用结构体定义。

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
inline void read(int &x)
{
    x=0; char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
}
const int INF=2147483647,N=10005,M=500005;
vector <int> a[N],l[N];
int dis[N],n,m,i,x,y,z,s;
bool f[N];
struct data
{
    int v,num;
    bool operator <(const data &x) const
    {
        return x.v<v;
    }
};
priority_queue <data> tree;
int main()
{
    read(n); read(m); read(s);
    for (i=1;i<=m;++i)
    {
        read(x); read(y); read(z);
        a[x].push_back(y); l[x].push_back(z);
    }
    for (i=1;i<=n;++i)
    dis[i]=INF;
    dis[s]=0; tree.push((data){0,s});
    while (!tree.empty())
    {
        int now=tree.top().num; tree.pop();
        if (f[now]) continue;
        f[now]=1;
        for (i=0;i<a[now].size();++i)
        {
            int k=a[now][i];
            if (dis[k]>dis[now]+l[now][i])
            {
                dis[k]=dis[now]+l[now][i];
                tree.push((data){dis[k],k});
            }
        }
    }
    for (i=1;i<=n;++i)
    printf("%d ",dis[i]);
    return 0;
}
                    
辣鸡老年选手AFO在即
原文地址:https://www.cnblogs.com/cjjsb/p/7911565.html