点多边少,邻接表
请编写程序求给定正权有向图的单源最短路径长度。图中包含n个顶点,编号为0至n-1,以顶点0作为源点。
输入格式:
输入第一行为两个正整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过1000。接下来e行表示每条边的信息,每行为3个非负整数a、b、c,其中a和b表示该边的端点编号,c表示权值。各边并非按端点编号顺序排列。
输出格式:
输出为一行整数,为按顶点编号顺序排列的源点0到各顶点的最短路径长度(不含源点到源点),每个整数后一个空格。如源点到某顶点无最短路径,则不输出该条路径长度。
输入样例:
4 4
0 1 1
0 3 1
1 3 1
2 0 1
输出样例:
1 1
#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e4+10;
#define INF 0x3f3f3f3f
int h[N],idx;
struct node
{
int to;
int w;
int next;
}e[N];
int n,m;
int dist[N],st[N];
void dijkstra()
{
memset(dist,0x3f,sizeof(dist));
dist[0] = 0;
for(int i=0;i<n-1;i++)
{
int t = -1;
for(int j=0;j<n;j++)
if(!st[j]&&(t == -1 || dist[j]<dist[t]))
{
t=j;
if(dist[n] == INF) break;
}
st[t] = true;
for(int j=h[t];j!=0;j = e[j].next)
dist[e[j].to] = min(dist[e[j].to],dist[t]+e[j].w);
}
}
void add(int u,int v,int w)
{
e[++idx].to = v;
e[idx].w = w;
e[idx].next = h[u];
h[u] = idx;
}
int main()
{
cin>>n>>m;
while(m--)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
dijkstra();
for(int i=1;i<n;i++)
if(dist[i] != INF) cout<<dist[i]<<" ";
return 0;
}