zoukankan      html  css  js  c++  java
  • luogu 4779 【模板】

    题目描述

    给定一个 N 个点,M 条有向边的带非负权图,请你计算从 S 出发,到每个点的距离。

    数据保证你能从 S 出发到任意点。

    输入输出格式

    输入格式:

     

    第一行为三个正整数 N, M,S。 第二行起 M 行,每行三个非负整数 u_i, v_i, w_i,表示从 u_i 到 v_i 有一条权值为 w_i 的边。

     

    输出格式:

     

    输出一行 N 个空格分隔的非负整数,表示 S 到每个点的距离。

    Input

    4 6 1

    1 2 2

    2 3 2

    2 4 1

    1 3 5

    3 4 3

    1 4 4

    output

    0 2 4 3


    算法 1:Dijkstra(入门写法)

     代码

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int n,m,s,f[1001][1001],dis[1001];
    bool vis[10001];
    void dij()
    {
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;
        for(int i=1;i<=n;++i) 
        {
            int pos=0;
            for(int j=1;j<=n;++j) 
                if(!vis[j] && dis[j]<dis[pos]) pos=j;
            vis[pos]=1;
            for(int j=1;j<=n;++j)
            {
                if(dis[pos]+f[pos][j]<dis[j]) 
                    dis[j]=dis[pos]+f[pos][j]; 
            }
        }
    } 
    
    int main()
    {
        memset(f,0x3f,sizeof(f));
         scanf("%d%d%d",&n,&m,&s);
         for(int i=1;i<=m;++i) 
         {
             int from,to,val;
             scanf("%d%d%d",&from,&to,&val);
             f[from][to]=min(f[from][to],val);
         }
         dij();
         for(int i=1;i<=n;++i) 
             printf("%d ",dis[i]);
        return 0; 
    } 

    算法 2:堆优化 Dijkstra

    代码:

    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int MX=500010;
    struct Edge {
        int to,next,val;
    }edge[MX];
    struct node {
        int pos,dis;
    };
    priority_queue<node> q;
    bool operator<(const node &a,const node &b){
        return a.dis>b.dis;
    }
    bool vis[MX];
    int first[MX],dis[MX],cnt,n,m,s;
    void add(int from,int to,int val)
    {
        edge[++cnt].to=to;
        edge[cnt].val=val;
        edge[cnt].next=first[from];
        first[from]=cnt;
    }
    
    void dij()
    {
        node st;
        st.pos=s,st.dis=0;
        q.push(st);
        while(!q.empty())
        {
            node curr=q.top();
            q.pop();
            int from=curr.pos,val=curr.dis;
            if(vis[from]) continue;
            vis[from]=1;
            for(int i=first[from];i;i=edge[i].next)
            {
                int to=edge[i].to;
                if(val+edge[i].val<dis[to])
                {
                    dis[to]=val+edge[i].val;
                    q.push((node){to,dis[to]});
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<=m;++i) {
            int from,to,val;
            scanf("%d%d%d",&from,&to,&val);
            add(from,to,val);
        }
        for(int i=1;i<=n;++i) 
            dis[i]=2147483647;
        dis[s]=0;
        dij();
        for(int i=1;i<=n;++i) 
            printf("%d ",dis[i]);
        return 0;
    }
    从0到1很难,但从1到100很容易
  • 相关阅读:
    【转载】我的七个建议Joel Spolsky
    C语言文件读写操作
    【转】RO段、RW段和ZI段 Image$$??$$Limit 含义(zz)
    给大家一个测试webservice的软件
    .net 实现深拷贝的方法
    第一次设计数据访问层,大家给你建议,谢谢
    重新写博客
    (转)理解 Thread.Sleep 函数
    slk解压缩
    SMTP Service设置
  • 原文地址:https://www.cnblogs.com/qseer/p/9597998.html
Copyright © 2011-2022 走看看