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;
}

 

posted @ 2018-09-06 14:17  qseer  阅读(235)  评论(0编辑  收藏  举报