【发布时间】:2017-08-27 20:58:36
【问题描述】:
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;
}
}
【问题讨论】:
-
这可能更适合Code Review。
-
adj[u].pb({w,v}); adj[v].pb({w,v});你确定这行得通吗?喜欢吗? -
@NikhilPathania 我认为他计算得太多了,如果我做同样的问题,我会简单地做 Dijkstra 和 DP 两遍:首先计算所有
dis[]的最小成本,然后使用 dp将这些方式加起来等于最低成本 -
这个试更正-新试更正循环不适合StackOverflow。
-
@n.m.好的,我没有读到这个
dp[v] = dp[u];,很抱歉这是我的错。我正在删除我之前的评论以防止混淆
标签: algorithm graph dynamic-programming dijkstra