一、找工作C++编程02--动态规划一(最小花费)

题目:现系里分配给你一个全球水库规划的任务,某些水库之间有双向的调度线路,要求将所给的所有水库以最小代价连通。
每条调度线路的代价跟水库里的常年储水量差、线路长度和水库等级差有关。设有n个水库,m条线路,每个水库常年储水量vi,

水库的等级k等于其度。线路的连通代价为(|v1-v2|+1) * d * (|k1-k2|+1)。

#include<iostream> 
#include<vector> 
#include<string> 
#include<cmath>

using namespace std; 

#define MAX_VEX_NUM 20// 最大顶点数
vector<string> allPath;  // 向量,用来存放所有的顶点 a 到顶点 i 的路径
vector<int> all;  //向量,用来存放对应路径的长度
struct MGraph //定义结构体

char vexs[MAX_VEX_NUM];// 顶点向量 // Adj Matrix 
int arcs[MAX_VEX_NUM][MAX_VEX_NUM];// 邻接矩阵
int vexnum,arcnum; 
}; 
MGraph G; // 申明一个无向图的邻接矩阵类型
int Locatevex(MGraph G ,char v)// 图的基本操作,寻找 V 的位置

int i=0; 
while(i<G .vexnum && v!=G .vexs[i]) 
i++; 
if(i<G .vexnum) 
return i;// 查找成功则返回顶点的下标
else 
return -1; 

int CreateUDG(MGraph &G) // 数组邻接矩阵表示法构造无向图

char v1,v2; 
int weight;// 权值
cin>>G.vexnum>>G .arcnum;  
if(G.vexnum>1000 &&G .arcnum>2000000){
return -1;
}
int v[G.vexnum] ;
for(int i=0;i<G .vexnum;i++)// 构造顶点向量
cin>>v[i];
for(int i=0;i<G .vexnum;i++)
   G.vexs[i]='1'+i; 
for(int q=0;q<G .vexnum;q++)// 初始化邻接矩阵
for(int p=0;p<G .vexnum;p++) 
G.arcs[q][p]=0; 
for(int k=0;k<G .arcnum;k++)// 构造邻接矩阵

cin>>v1>>v2>>weight;
if(weight>100000){
return -1;
}  
int a=Locatevex(G ,v1); 
int b=Locatevex(G ,v2); 
G.arcs[a][b]=weight*(abs(v[v1]-v[v2])+1)*(abs(v1-v2)+1); 
G.arcs[b][a]=G .arcs[a][b]; 

return 1; 
}//Create UDG 
void Minway(MGraph G ,bool *visited,char vexs,int Long,char vb,string path)  // 递归求取所有顶点 a 到顶点 i 的路径

if(vexs==vb)  // 递归结束条件

path=path+" "+vexs; 
allPath.push_back(path);  //将路径放入向量中
all.push_back(Long);  // 将路径长放入对应向量中

else 

path=path+" "+vexs; 
int i=Locatevex(G ,vexs); 
visited[i]=true; 
for(int j=0;j<G .vexnum;j++) 
if((!visited[j])&&(G .arcs[i][j]!=0)) 

Minway(G ,visited,G .vexs[j],Long+G .arcs[i][j],vb,path);  // 递归调用自身

visited[i]=false;  // 退出递归前清除访问记录


void CountMinway(MGraph G)  // 该函数调用递归部分实现递归

char va='1';
char vb='0'+G.vexnum; 
string path;  // 存放路径
int i=Locatevex(G ,va); 
bool visited[100]; 
for(int j=0;j<G .vexnum;j++) 
visited[j]=false;  //初始化访问记录,全都未访问过
visited[i]=true;  // 起点顶点设为访问过
int Long=0; 
path+=va; 
for(int j=0;j<G .vexnum;j++) 
if(G.arcs[i][j]!=0) 

Long=G .arcs[i][j]; 
Minway(G ,visited,G.vexs[j],Long,vb,path); // 调用递归部分

cout<<endl; 

void Minway()// 输出最短路径

int min=10000; 
for(int i=0;i<allPath.size();i++)
if(all[i]<min) 
min=all[i]; 
for(int j=0;j<allPath.size();j++)
if(all[j]==min) 
cout<<all[j]<<endl; 
cout<<endl; 

int main() 

CreateUDG(G);  // 建图
CountMinway(G);  // 找出所有路径
Minway();  // 输出最短路径
return 0;


猜你喜欢

转载自blog.csdn.net/moshangqingcheng/article/details/80861678
今日推荐