1. 求有向无环图中节点s到节点t的最短路径
#include<iostream>
#include<vector>
#include<map>
#include<climits>
#include<iomanip>
using namespace std;
const int INF = INT_MAX/2;
// graph
const int nodes = 6;
const int k = nodes - 1;
// define OPT
vector<int> OPT(nodes, INF);
map<int,int> next_node;
// 用于DAG,有向无环图,当有环时,会有循环依赖性,此算法无法解决循环依赖性问题,bellman_ford算法解决了循环依赖性问题
int shortest_path(vector< vector<int> > G, int start, int end);
int opt(vector< vector<int> > G, int v);
int main(){
// define graph
vector< vector<int> > G(nodes, vector<int>(nodes, INF));
// graph
G[0][1] = 1;
G[0][2] = 1;
G[1][2] = 3;
G[1][3] = 4;
G[1][4] = 6;
G[2][3] = 5;
G[2][4] = 6;
G[3][4] = 7;
G[3][5] = 8;
G[4][5] = 9;
int start = 0, end = 5;
int shortest_path_value = shortest_path(G, start, end);
cout<<shortest_path_value<<endl;
for(auto a:OPT) cout<<a<<" ";
cout<<endl;
for(int i=0; i<nodes; i++){
if(i==end) continue;
cout<<i<<"->";
int count = 0;
int curr_node = i;
while( count++<nodes & next_node[curr_node]!=end){
cout<<next_node[curr_node]<<"->";
curr_node = next_node[curr_node];
}
cout<<end<<endl;
}
return 0;
}
int shortest_path(vector< vector<int> > G, int start, int end){
OPT[end] = 0;
opt(G,start);
return OPT[start];
}
int opt(vector< vector<int> > G, int v){
if(OPT[v]<INF){
return OPT[v];
}
for(int w=0; w<nodes; w++){
if(G[v][w]<INF){
// OPT[v] = G[v][w] + opt(G,w) < OPT[v] ? G[v][w] + opt(G,w) : OPT[v];
if(G[v][w] + opt(G,w) < OPT[v]){
OPT[v] = G[v][w] + opt(G,w);
next_node[v] = w;
}
}
}
return OPT[v];
}
2.任给一个图,求图中节点s到节点t不超过K步的最短路径,即Bellman Ford算法【1956,1958】
#include<iostream>
#include<vector>
#include<map>
#include<climits>
#include<iomanip>
using namespace std;
const int INF = INT_MAX/2;
// graph 1
// const int nodes = 6;
// graph 2
const int nodes = 5;
const int k = nodes - 1;
// define OPT
vector< vector<int> > OPT(nodes, vector<int>(nodes, INF));
map<int,int> next_node;
vector<int> path;
// 用于DAG,有向无环图, 但没有解决循环依赖性问题
int shortest_path(vector< vector<int> > G, int start, int end);
int opt(vector< vector<int> > G, int v);
// 解决了循环依赖性的问题
int bellman_ford(vector< vector<int> > G, int start, int end);
int min(vector< vector<int> > G, int i, int k, int start);
int main(){
// define graph
vector< vector<int> > G(nodes, vector<int>(nodes, INF));
// graph 1
// G[1][0] = -3;
// G[1][2] = -4;
// G[2][4] = -1;
// G[2][5] = -2;
// G[3][2] = 8;
// G[3][0] = 3;
// G[4][0] = 4;
// G[4][1] = 6;
// G[5][0] = 2;
// G[5][3] = -3;
// graph 2
G[0][1] = 3;
G[0][3] = 7;
G[1][2] = 5;
G[1][4] = 5;
G[2][3] = 6;
G[2][4] = 2;
G[3][0] = 2;
G[4][0] = 6;
G[4][2] = 1;
G[4][3] = 3;
//bellman_ford algorithm
int shortest_value = bellman_ford(G, 1, 0);
cout<<shortest_value<<endl;
for(auto x:OPT){
for(auto a:x){
if(a==INF){
cout<<setw(4)<<right<<"-"<<" ";
}else{
cout<<setw(4)<<right<<a<<" ";
}
}
cout<<endl;
}
for(auto a:next_node) cout<<a.first<<" : "<<a.second<<endl;
for(int i=1; i<nodes; i++){
cout<<i<<"->";
int count = 0;
int curr_node = i;
while( count++<nodes & next_node[curr_node]!=0){
cout<<next_node[curr_node]<<"->";
curr_node = next_node[curr_node];
}
cout<<0<<endl;
}
return 0;
}
int bellman_ford(vector< vector<int> > G, int start, int end){
for(int k=0; k<nodes; k++){
OPT[end][k] = 0;
}
for(int k=1; k<nodes; k++){
for(int v=1; v<nodes; v++){
OPT[v][k] = min(G,v,k,start);
}
}
return OPT[start][nodes-1];
}
int min(vector< vector<int> > G, int v, int k, int start){
int min_val = OPT[v][k-1];
int node = -1; // 选中的节点
for(int w=0; w<nodes; w++){
if(G[v][w]<INF){ // 节点v -> 节点w 存在一条边
// min_val = (OPT[w][k-1] + G[v][w]) < min_val ? OPT[w][k-1] + G[v][w] : min_val;
if( (OPT[w][k-1] + G[v][w]) < min_val ){
min_val = OPT[w][k-1] + G[v][w];
node = w;
next_node[v] = w;
}
}
}
if(min_val>(INF/2)){
min_val = OPT[v][k-1];
}
return min_val;
}