POJ 3249 拓扑排序+动态规划
来源:互联网 发布:vc mfc编程实例教程 编辑:程序博客网 时间:2024/05/17 08:22
该题是让求在一个有向无环图中,从一个入度为 0 的节点出发,到一个出度为 0 的节点的最大的权值问题。我们可以使用广搜,但是会超时,上网查了一下解题报告,可以使用拓扑排序+动态规划来解决此问题:
dp[1] = max{ dp[2] + cost[1] , dp[3] + cost[1] };
dp[2] = cost[2] + dp[4];
dp[3] = cost[3] + dp[4];
dp[4] = cost[4];
dp[5] = cost[5] + dp[6];
dp[6] = cost[6];
在拓扑排序的过程中,是入度为0的节点先入队列,所以我们可以做一个逆置思考,是的 dp[i] 存储的是入度为零的节点到当前节点的最大权值和,而最后在出度为 0 的节点的 dp[i] 中搜索最大的权值。代码实现如下:
#include <iostream>#include <queue>#include <cstdio>using namespace std;#define N 100100#define M 1000100#define INF 1<<29struct node{ int v; int next;} edge[M];int dp[N]; // 最大价值 存储 由 拓扑排序后 入度为0的节点到当前节点最大的 profitint enext[N]; //记录节点 i 当前的边,由当前的边 推出 下一条边int indegree[N]; //入度int cost[N]; //价值int res;int idx;std::queue<int > q;int m,n,a,b,i,j;void input(){ for(i=1;i<=n;i++) { scanf("%d",&cost[i]); dp[i] = -INF; indegree[i] = 0; } idx=0; //memset(dp,-INF,sizeof(int)*(n+10) ); //memset(indegree,0,sizeof(int)*(n+10) ); //节点度数初始化为0 memset(enext,-1,sizeof(enext) ); //说明当前节点只此一条边 for(i=1;i<=m;i++) { scanf("%d %d",&a,&b); edge[idx].v = b; edge[idx].next = enext[a]; enext[a] = idx++; indegree[b]++; } while( !q.empty() ) q.pop(); for( i=1;i<=n;i++) if( !indegree[i] ) q.push(i),dp[i]=cost[i];}int dag(){ res = -INF; while( !q.empty() ) { int cur = q.front(); q.pop(); bool flag = true; //只有节点的出度为 0 的时候,我们才判断其是否有最大profit int nextid; // cout<<"cur : "<<cur<<endl; for( i=enext[cur] ; i != -1 ; i = edge[i].next) //遍历当前顶点的所有的边 { flag = false; nextid = edge[i].v ; // cout<<"nextid : "<<nextid<<endl; if( dp[nextid] < cost[ nextid ] + dp[cur]) dp[nextid] = cost[nextid] + dp[cur]; indegree[nextid]--; if( !indegree[nextid] ) { q.push(nextid); } } if( flag && dp[cur] > res ) res = dp[cur]; } return res;}int main(){ while(scanf("%d %d",&n,&m) != EOF) { input(); printf("%d\n",dag()); } return 0;}
说明:本题对时间要求很苛刻,由于数据量大,输入输出必须用 scanf 和 printf 才能保证不超时,同时要避免使用 动态的开辟空间,new 和 delete 同样会有很大的时间开销。
- POJ 3249 拓扑排序+动态规划
- poj 3249(DP+拓扑排序)
- Test for Job (动态规划 + 拓扑排序)
- Test for Job (动态规划 + 拓扑排序)
- 【codevs2488】绿豆蛙的归宿 动态规划+拓扑排序
- codeforces 721C journey(动态规划+拓扑排序)
- POJ 3249 拓扑排序+ 简单DP
- poj 3249 Test for Job (拓扑排序)
- 拓扑排序,poj 1094
- 拓扑排序,poj 1094
- POJ 1094 拓扑排序
- poj-1094拓扑排序
- poj 1094 拓扑排序
- POJ 3687 拓扑排序
- POJ 3687 拓扑排序
- POJ 1270 拓扑排序
- POJ 2585 拓扑排序
- poj 1094 拓扑排序
- 数据库中的Schema
- Hibernate检索方式
- 电影 大侦探福尔摩斯2
- Linux开发环境必备工具(命令篇)
- windows CMD 快捷命令大全
- POJ 3249 拓扑排序+动态规划
- ubuntu下minicom不能接受键盘输入
- DIV/CSS:一个贴在左上角的标签
- 【郭林专刊】较好的代码维护实践 .
- kernel下载,编译
- N!分解素因子及若干问题
- SDK:用GetWindowRect GetClientRect 获得控件在客户区的RECT
- String format
- 被坑死了。。。