我正在做一个问题,我必须计算从一个特定节点(起始节点)到定向图表中所有其余节点的总成本,然后从这些节点到起始节点。 现在问题的第一部分,即从开始到其余的节点,我已经应用了dijkstra的算法,但是对于第二部分,我想到将每个节点作为源循环并使用dijkstra&s进行处理。每个节点。但是,如果我没有弄错的话,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;
}
答案 0 :(得分:2)
您应该使用产生shortest-path tree的寻路算法。 Dijkstra算法和Bellman-Ford算法都可以用于此。哪个会表现更好将取决于density of your graph。对于稀疏图,Dijkstra的算法会更快。
然后您可以执行以下操作: