最长路径问题dp

来源:互联网 发布:温差发电片相关数据 编辑:程序博客网 时间:2024/05/21 22:56

看了Geek_ling的博文后写的代码,原先也写过最长路径问题(uva10000),不过用的是spfa算法

具体的讲解戳 http://www.cnblogs.com/yanlingyin/archive/2011/11/12/2246716.html

求子问题之前先进行拓扑排序,然后根据状态方程 :dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}; dilg(v)表示从源点 到 v 点的最长路径长度。还是比较容易理解的。

#include <iostream>using namespace std;const int maxn = 100;int map[maxn][maxn];int pre[maxn];//入度bool has[maxn];//是否排序int order[maxn];//拓扑序列int edge_num;//边的数量int node_num;int dp[maxn];//dp[i] 从源节点 到i节点的 最长路径长度int parent[maxn];//节点i的前驱节点void init(){int one,two,weight;memset(pre,0,sizeof(pre));memset(map,0,sizeof(map));for(int i = 0;i < edge_num;i++){cin>>one>>two>>weight;map[one][two] = weight;pre[two]++;}memset(has,false,sizeof(has));memset(dp,-1,sizeof(dp));}void topo(int dep)//首次调用时dep = 1 order[1---node_num]{for(int i = 1;i < maxn && dep <= node_num;i++){if(!has[i] && pre[i]==0){has[i] = true;order[dep] = i;for(int k = 1;k < maxn;k++){if(map[i][k] != 0)pre[k]--;}dep++;i = 0;//每次从开头开始遍历 这部分处理的不好,因为后面的数字 会判断为一个个的 独立 结点if(dep > node_num)break;}}}void solve(){memset(parent,0,sizeof(parent));memset(dp,0,sizeof(dp));for(int i = 1;i <= node_num;i++)//自底向上求解子问题{for(int j = 1;j < maxn;j++){if(map[j][order[i]]){if(dp[order[i]] < dp[j] + map[j][order[i]]){dp[order[i]] = dp[j] + map[j][order[i]];parent[order[i]] = j;}}}//for int j}//for int i}void print(int n){if(parent[n] != 0)print(parent[n]);cout<<n<<" ";}int main(){freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int goal;while(cin>>node_num>>edge_num){init();topo(1);solve();cin>>goal;print(goal);cout<<endl;}return 0;}

测试数据:

6 8
6 1 1
6 3 2
3 1 4
1 2 6
3 4 3
2 4 1
2 5 2
4 5 1
5

输出:

6 3 1 2 5


0 0
原创粉丝点击