• 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在即
  • 相关阅读:
    Docker大行其道—镜像
    Google 推出全新的两步验证机制
    安全警告——“Windows已经阻止此软件因为无法验证发行者”解决办法
    Word2010 自动生成二级编号
    正则表达式判断汉字
    c# IList<T> 深拷贝
    C#IList 取区间数据
    Oracle 同环比排除分母0
    Git 删除服务器的远程分支
    【转】C#获取当前路径7种方法
  • 原文地址:https://www.cnblogs.com/cjjsb/p/7911565.html
Copyright © 2020-2023  润新知