图中所有节点到特定节点的最短路径成本
Posted
技术标签:
【中文标题】图中所有节点到特定节点的最短路径成本【英文标题】:Shortest path cost from all nodes to a particular node in a graph 【发布时间】:2016-10-31 10:35:22 【问题描述】:我正在做一个问题,我必须计算从一个特定节点(起始节点)到 有向 图中的所有其余节点然后返回的总成本这些节点到起始节点。 现在对于问题的第一部分,即从开始到其余节点,我已经应用了 dijkstra 算法,但对于第二部分,我想将每个节点作为源循环并为每个节点使用 dijkstra。但是,如果我没记错的话,dijkstra 会计算从一个源节点到其余节点的路径成本,在这种情况下会导致大量开销。对于问题的第二部分,我只需要从所有节点到一个特定节点的最短路径。
这是我一直在做的(忽略getchar,那只是为了加快输入)。
#include<set>
#include<stdio.h>
#include<vector>
#include<limits.h>
#include<cstdio>
using namespace std;
#define mp make_pair
#define ft first
#define sd second
#define gc getchar
vector< pair<int,int> > g[101000];
int n,m,sum,i,j,k,t,x,y,z;
vector<int> dist;
vector <int> vis;
void scanint(int &x)
register int c = gc();
x=0;
for(;(c<48||c>57);c=gc());
for(;c>47&&c<58;c=gc())
x=(x<<1)+(x<<3)+c-48;
void dijkstra(int source)
dist.clear();
int i,j,k;
for(i=0;i<n;i++)
dist.push_back(INT_MAX);
vis.push_back(0);
dist[source] = 0;
set< pair<int,int> > s; // pair is dist, node_number
set< pair<int,int> >::iterator it;
for(i=0;i<n;i++)
s.insert(mp(dist[i],i));
while(!s.empty())
it = s.begin();
pair<int,int> temp = *it;
s.erase(temp); // remove minimum val node
int cur = temp.sd;
int val = temp.ft;
if(val == INT_MAX)
return;
for(i=0;i<g[cur].size();i++)
int nb = g[cur][i].ft;
if(!vis[nb] && dist[nb] > val + g[cur][i].sd)
s.erase(mp(dist[nb],nb)); // erase old val
dist[nb] = val + g[cur][i].sd;
s.insert(mp(dist[nb],nb));
s.clear();
int main()
// std::ios::sync_with_stdio(false);
scanint(t);
for(int r=0;r<t;r++)
dist.clear();
vis.clear();
scanint(n);
scanint(m);
for(i=0;i<m;i++)
g[i].clear();
for(i=0;i<m;i++)
scanint(x);
scanint(y);
scanint(z);
x--; y--;
g[x].push_back(mp(y,z));
dijkstra(0);
sum=0;
for(int i=0;i<n;i++)
sum=sum+dist[i];
for(int i=0;i<n;i++)
dijkstra(i);
sum=sum+dist[0];
printf("%d\n",sum);
g[x].clear();
for(int i=0;i<n;i++)
dist[i]=INT_MAX;
return 0;
【问题讨论】:
在无向图中 minPath(a,b)=minPath(b,a)。因此,您可以将从一个节点转移到其他节点的成本翻倍 @AlexanderAnikin 是单向的不是无向的,不能用同一个路径回溯。 @AlexanderAnikin:这取决于您所说的“单向”是什么意思。我猜它的意思是“导演”。在这种情况下,您的陈述是错误的。可能没有从“b”到“a”的路径。 老实说,我不知道 unidirected 是什么意思——它不规范。如果它是有向图,我的评论与案例无关,如果它是“无向”或模拟无向(当你制作两条有向边而不是一条无向边时),评论是有效的。 将单向更新为定向 【参考方案1】:您应该使用产生shortest-path tree 的寻路算法。 Dijkstra 算法和 Bellman-Ford 算法都可以用于此。他们中的哪一个会表现更好将取决于density of your graph。对于稀疏图,Dijkstra 算法会更快。
然后您可以执行以下操作:
-
从源节点计算最短路径树。您现在将拥有从源节点到所有目的地的路径。
反转图中所有边的方向,并再次从源节点计算最短路径树。这棵树现在将包含从目标节点到原始源节点的最短路径。
【讨论】:
以上是关于图中所有节点到特定节点的最短路径成本的主要内容,如果未能解决你的问题,请参考以下文章