多段图算法

来源:互联网 发布:多线程查询数据库 编辑:程序博客网 时间:2024/06/04 00:21

多段图就是这么一幅图:


分成多段,计算第一段到最后一段的最短距离。

对其使用动态规划法:

阶段:将图中的顶点划分5个阶段,k

状态:每个阶段有几种供选择的点s

决策:当前状态应在前一个状态的基础上获得。决策需要满足规划方程

规划方程:f(k)表示状态k到终点状态的最短距离。

初始条件:f(k)=0;

方程:f(k-1)=min{f(k)+W(k-1,k)}其中W(k-1,k)表示状态k-1到状态k的距离


#include<iostream>#include<cstdio>#include<vector> #include<algorithm>#include<cstring> #include<cmath> #include<stack>using namespace std;#define MAX 0x7fffffffstruct Node{int ids;int len;}nodes;vector<Node> vv[100];//构造图 int N,E; //段数,边数 //int num[100]; //记录每段点个数 int dis[100]; //记录每点到最后一段的长度 vector<int> seg[100]; //记录每段点号 int ans;stack<int> sta;bool book[100];bool flag;void init(){for(int i=0;i<100;i++)dis[i] = MAX;for(int i=0;i<100;i++){vv[i].clear();seg[i].clear();}while(!sta.empty()){sta.pop();}memset(book,false,sizeof(book));flag = false;}void DFS(int arg,int dist){int nowlen;int len = vv[arg].size();for(int i=0;i<len;i++){sta.push(vv[arg][i].ids);nowlen = dist+vv[arg][i].len;if(nowlen == ans && book[vv[arg][i].ids]){flag = true;return;} DFS(vv[arg][i].ids, nowlen);if(flag){return; }sta.pop();}}void DFSPrint(){int i = sta.top();sta.pop();if(!sta.empty())DFSPrint();cout<<i<<" ";}void algo(){//最后一段初始化为0 int l = seg[N].size();for(int i=0;i<l;i++){dis[seg[N][i]] = 0;book[seg[N][i]] = true;}//DP过程 for(int i=N-1;i>0;i--){int len = seg[i].size();for(int j=0;j<len;j++){int nowpoint = seg[i][j];int len2 = vv[nowpoint].size();for(int k=0;k<len2;k++){Node nn = vv[nowpoint][k];int toid = nn.ids;//dis[nowid] = nn.len+dis[nowid] dis[nowpoint] = min(dis[nowpoint], nn.len+dis[toid]);}}}//找到最短距离ans = MAX;l =  seg[1].size();int imp; for(int i=0;i<l;i++){//ans = min(ans, dis[seg[1][i]]);if(ans > dis[seg[1][i]]){imp = seg[1][i];ans = dis[seg[1][i]];}}//回溯找符合要求的点sta.push(imp);DFS(imp,0);}int main(){int t,tp;while(true){init();cout<<"请输入段数:"<<endl;cin>>N;for(int i=1;i<=N;i++){cout<<"请输入第"<<i<<"段节点数:"<<endl;cin>>t;cout<<"请输入第"<<i<<"段节点号:"<<endl;for(int j=0;j<t;j++){cin>>tp;seg[i].push_back(tp);}}cout<<"请输入边数:"<<endl;cin>>E;cout<<"请输入边关系:"<<endl;for(int i=0;i<E;i++){cin>>t>>nodes.ids>>nodes.len;vv[t].push_back(nodes);}algo();cout<<"最短距离为:"<<endl;cout<<ans<<endl<<endl;cout<<"符合要求的点为:"<<endl;DFSPrint();cout<<endl<<endl; } return 0;} /*41132 3 435 6 718101 2 21 3 31 4 72 6 103 5 23 7 34 6 15 8 46 8 57 8 6*//*51142 3 4 536 7 839 10 11112211 2 91 3 71 4 31 5 22 6 42 7 22 8 13 6 23 7 74 8 115 7 115 8 86 9 66 10 57 9 47 10 38 10 58 11 69 12 410 12 211 12 5 */ 
测试结果截图:


算法课上的一道作业,相对比较简单的图论+DP问题吧。

1 0