动态规划-多段图问题
时间复杂度分析:
这份代码用到了两种方法:
- 1 遍历每个相邻阶段,下一个阶段只会依赖于前一个阶段,通过不断遍历,逐渐把最终结果转移到起始节点。时间复杂度平均下来为 O(n2/k)
- 2 时间复杂度为O(n * k)
运行结果
代码:
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int g[9][9], cost[9];
vector<int> layer[6];
void initLayer(){
layer[0].push_back(0), layer[1].push_back(1),layer[1].push_back(2);
layer[2].push_back(3), layer[2].push_back(4),layer[2].push_back(5);
layer[3].push_back(6), layer[3].push_back(7),layer[4].push_back(8);
}
void initGraph(){
memset(g, 0x3f, sizeof g);
g[0][1] = 5, g[0][2] = 2, g[1][3] = 3, g[1][4] = 3, g[2][3] = 6;
g[2][4] = 5, g[2][5] = 8, g[3][6] = 1, g[3][7] = 4, g[4][6] = 6;
g[4][7] = 2, g[5][6] = 6, g[5][7] = 2, g[6][8] = 7, g[7][8] = 3;
}
int main()
{
initLayer();
initGraph();
//1.第一种做法: -----------------------------------------------------
memset(cost, 0x3f, sizeof cost);
cost[8] = 0;
for(int i = 3; i >= 0; i --)
{
int j = i + 1;
int cnta = i, cntb = j;
for(int x = 0; x < layer[cnta].size(); x ++)
{
for(int y = 0; y < layer[cntb].size(); y ++)
{
int a = layer[cnta][x], b = layer[cntb][y];
if(g[a][b] == 0x3f3f3f3f) continue;
cost[a] = min(cost[a], cost[b] + g[a][b]);
}
}
}
cout << "最短路径长度为:" << cost[0] << endl;
//第二种做法; -------------------------------------------------------------
memset(cost, 0x3f, sizeof cost);
cost[8] = 0;
for(int i = 8; i >= 0; i --)
{
for(int j = i + 1; j <= 8; j ++)
{
if(g[i][j] == 0x3f3f3f3f) continue;
cost[i] = min(cost[i], cost[j] + g[i][j]);
}
}
vector<int> res;
res.push_back(0);
int nextv = 0;
for(int i = 0; i <= 3; i ++) //每次都选取 i 节点所达节点最小的 cost[j]
{
int minv = 0x3f3f3f3f;
int cntv = 0;
for(int j = 0; j <= 8; j ++)
{
if(g[nextv][j] == 0x3f3f3f3f) continue;
if(cost[j] + g[nextv][j] < minv){
cntv = j;
minv = cost[j] + g[nextv][j];
}
}
nextv = cntv;
res.push_back(cntv);
}
cout << "最短路径长度为:" << cost[0] << endl;
for(int x = 0; x < res.size(); x ++)
{
if(x != res.size() - 1)
cout << res[x] << "-->";
else cout << res[x] << endl;
}
return 0;
}