题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入输出格式
输入格式:
第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。
接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。
输出格式:
一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于20%的数据:N<=5,M<=15
对于40%的数据:N<=100,M<=10000
对于70%的数据:N<=1000,M<=100000
对于100%的数据:N<=10000,M<=500000
样例说明:
(图片1到3和1到4的文字位置调换)
思路:spfa 或 dijkstra 跑最短路(话说我没大用dijkstra,一般都是用spfa。。。)
难度:普及/提高-
#include<algorithm> #include<cstdio> #include<queue> #define MAXN 0x7fffffff #define M 500001 using namespace std; queue<int> q; int n, m, s; int tot; int dis[M], vis[M]; int to[M*2], head[M*2], cap[M*2], net[M*2]; void add(int u, int v, int w) { to[++tot] = v; net[tot] = head[u]; head[u] = tot; cap[tot] = w; } void spfa(int x) { //spfa核心代码 for(int i = 1; i <= n; i++) vis[i] = 0, dis[i] = MAXN; dis[x] = 0; vis[x] = 1; q.push(x); while(!q.empty()) { int y = q.front(); q.pop(); vis[y] = 0; for(int i = head[y]; i; i = net[i]) { int t = to[i]; if(dis[t] > dis[y]+cap[i]); dis[t] = dis[y]+cap[i]; if(!vis[t]) vis[t] = 1, q.push(t); } } } int main() { scanf("%d%d%d", &n, &m, &s); for(int i = 1; i <= m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); } spfa(s); for(int i = 1; i <= n; i++) printf("%d ", dis[i]); return 0; }