最短路 (Spfa)

    xiaoxiao2021-03-25  149

    问题描述

    给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

    输入格式

    第一行两个整数n, m。

    接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

    输出格式 共n-1行,第i行表示1号点到i+1号点的最短路。 样例输入 3 3 1 2 -1 2 3 -1 3 1 2 样例输出 -1 -2 数据规模与约定

    对于10%的数据,n = 2,m = 2。

    对于30%的数据,n <= 5,m <= 10。

    对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

    题解:dijkstra不能处理有负权的边。floyd:O(n^3),还卡TM的内存....所以只能用Spfa了...

    代码:

    #include<bits/stdc++.h> using namespace std; struct point { int v,next,cap; } edge[20010*10]; int head[20010]; int dis[20010]; bool vis[20010]; int len, n, m; void addedge(int from, int to, int cap) { edge[len].v = to; edge[len].cap = cap; edge[len].next = head[from]; head[from] = len++; } void spfa(int start) { queue<int>q; for(int i = 0; i <= n; i++){ dis[i] = 99999999; vis[i] = 0; } q.push(start); dis[start] = 0; vis[start] = 1; while(!q.empty()) { int x = q.front(); q.pop(); vis[x] = 0; for(int i = head[x]; i != -1; i = edge[i].next) { int v = edge[i].v; if(dis[v] > dis[x] + edge[i].cap){ dis[v] = dis[x] + edge[i].cap; if(!vis[v]){ vis[v] = 1; q.push(v); } } } } } int main() { int u,v,l; cin>>n>>m; len = 0; memset(head,-1,sizeof(head)); for(int i=0;i<m;i++){ cin>>u>>v>>l; addedge(u,v,l); } spfa(1); for(int i = 2; i <= n; i++){ cout<<dis[i]<<endl; } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1614.html

    最新回复(0)