从所有节点到图中特定节点的最短路径成本

时间:2016-10-31 10:35:22

标签: c++ algorithm graph dijkstra

我正在做一个问题,我必须计算从一个特定节点(起始节点)到定向图表中所有其余节点的总成本,然后从这些节点到起始节点。 现在问题的第一部分,即从开始到其余的节点,我已经应用了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;
}

1 个答案:

答案 0 :(得分:2)

您应该使用产生shortest-path tree的寻路算法。 Dijkstra算法和Bellman-Ford算法都可以用于此。哪个会表现更好将取决于density of your graph。对于稀疏图,Dijkstra的算法会更快。

然后您可以执行以下操作:

  1. 计算源节点的最短路径树。现在,您将拥有从源节点到所有目的地的路径。
  2. 反转图形中所有边的方向,并再次计算源节点中的最短路径树。此树现在将包含从目标节点到原始源节点的最短路径。