从固定节点以最低成本到达节点的方式数

时间:2017-04-03 05:29:49

标签: algorithm graph dynamic-programming dijkstra

weighted graph中有n个节点(1,2 .. n),m(m> n)bi-directional edges

所有权重均为positive,且no multiple edges

one fixed origin(节点1)。我们将始终从起源出发。

现在我们必须找到number of ways (path) to reach each of the nodes(starting from the origin) with minimum cost

(All paths counted should have the minimum cost to reach that node from the origin)

输入 - 第一行包含n,m。

接下来的m行包含u,v,w。 => u和v之间存在重量w(w> 0)的边缘。

输出 - 为原点以外的每个节点打印n-1行一行,包含到达每个节点的方式(从原点开始),且成本最低。

样品测试 -

4 5

1 2 5

1 3 3

3 2 2

3 4 7

2 4 5

输出 -

2

1

3

这是我的解决方案,请检查这是否适用于所有情况,我做了Dijkstra + DP。我不确定代码的正确性。

#define pp pair<int,int>
vector< pp > adj[N]; //List to store graph
int dis[N],dp[N];

int main()
{
  ios::sync_with_stdio(0);
  int i,j,k,m,n,t;
  cin>>n>>m;
  for(i=0;i<m;i++)
  {
   int u,v,w;
   cin>>u>>v>>w;

   adj[u].push_back({w,v});       
   adj[v].push_back({w,v});
  }
priority_queue< pp , vector<pp > , greater<pp> > pq;   //Min Priority Queue
for(int i=0;i<=n;i++) dis[i] = INT_MAX;
dis[1] = 0;
dp[1] = 1;
pq.push({0,1});

while(!pq.empty())
{
  pp tp = pq.top();
  int u = tp.second;
  int d = tp.first;
  pq.pop();
  if(dis[u]<d) continue;       // We have better ans, so continue.

  for(i=0;i<adj[u].size();i++)  // Traversing all the egdes from node u 
    {
      int v = adj[u][i].second;  //Adjacent vertex v .
      int w = adj[u][i].first;
      if(d + w <= dis[v] )
       {
        if(d+w==dis[v])
        dp[v] += dp[u];     //Add the possible ways to the v from u

        if(d + w < dis[v])
          {
           dis[v] = d + w;  
           dp[v] = dp[u];   // Better ans so set it directly.
           pq.push({dis[v],v});  //Better ans found so push it into queue.
          }
       }
    }
 }

 cout<<endl;

 for(int i = 1;i<=n;i++)
 {
   cout<<i<<" dis = "<<dis[i]<<" ways = "<<dp[i]<<endl;
 }
 }

1 个答案:

答案 0 :(得分:0)

我认为你通过计算最小距离和没有问题来使问题过于复杂。一起的路径。

  • 我想你首先正常运行dijsktra并计算最小值 在一次运行中从源节点到所有其他节点的距离
  • 然后,将现有双向边缘的当前图形修改为节点u - >的单向边缘。节点 v,来自源节点S的distance[v] >= distance[u]。这将产生带有源S的分层图。
  • 此后你可以从源节点运行BFS或DFS 算不了通过添加no来到达该节点的方法到达每个父节点的方式。