POJ 3249 Test for Job 拓扑排序+DP

http://poj.org/problem?id=3249

题意:

给一个有向无环图DAG(不一定联通),每个点有权值,入度为0的点为起点,出度为0的点为终点,选择一个起点走到一个终点,使得路上的权和最大。

分析:

dp[to] = max(dp[from]) + value[to],然后先拓扑排序保证状态正确转移即可,终点做标记,如果是终点则尝试更新答案。

update:因为点权可以为负,所以程序里用dp[i] == -1表示未访问过该点是有问题的,不过没有遇上会卡掉这种情况的数据=。=

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6
 7 int n, m, esize, x, y;
 8 int a[100100], en[100100], in[100100], bfn[100100], dp[100100];
 9 bool ed[100100];
10 struct edge{
11     int v, n;
12 } e[1000100];
13 void addedge(int u, int v)
14 {
15     e[esize].v = v;;
16     e[esize].n = en[u];
17     en[u] = esize ++;
18 }
19 queue<int> q;
20 int main()
21 {
22     while(scanf("%d%d", &n, &m) != EOF)
23     {
24         for (int i = 1; i <= n; i++)
25             scanf("%d", a+i);
26         memset(en, -1, sizeof(en));
27         memset(in, 0, sizeof(0));
28         memset(ed, true, sizeof(ed));
29         esize = 0;
30         for (int i = 0; i < m; i++){
31             scanf("%d %d", &x, &y);
32             addedge(x, y);
33             in[y]++;
34             ed[x] = 0;
35         }
36         for (int i = 1; i <= n; i++)
37             if (!in[i]) q.push(i);
38         int ans = -2147483640;
39         int cnt = 0;
40         while(!q.empty())
41         {
42             int u = q.front(); q.pop();
43             bfn[cnt++] = u;
44             for (int t = en[u]; t != -1; t = e[t].n){
45                 int v = e[t].v;
46                 in[v] --;
47                 if (in[v] == 0)    q.push(v);
48             }
49         }
50         memset(dp, -1, sizeof(dp));
51         for (int i = 0; i < n; i++){
52             int u = bfn[i];
53             if (dp[u] == -1) dp[u] = a[u];
54             if (ed[u]) ans = max(ans, dp[u]);
55             for (int t = en[u]; t != -1; t = e[t].n){
56                 int v = e[t].v;
57                 if (dp[v] == -1 || dp[v] < dp[u] + a[v])
58                     dp[v] = dp[u] + a[v];
59             }
60         }
61         printf("%d\n", ans);
62     }
63     return 0;
64 }

POJ 3249 Test for Job 拓扑排序+DP,布布扣,bubuko.com

时间: 2024-09-29 03:34:24

POJ 3249 Test for Job 拓扑排序+DP的相关文章

POJ 3249 拓扑排序+DP

貌似是道水题.TLE了几次.把所有的输入输出改成scanf 和 printf ,有吧队列改成了数组模拟.然后就AC 了.2333333.... Description: MR.DOG 在找工作的过程中呢.遇见了这样一个问题.有n个城市,m条小道.然后要从入度为0的点出发,出度为0的点结束,中途经过的城市呢,都是要付费的.负数表示花费.正数表示收益.然后让你求收益最大或者说花费最少的总值. 貌似.BFS和DFS都会超时.不妨一试.附代码: #include<stdio.h>#include<

POJ 1128 Frame Stacking(拓扑排序&amp;#183;打印字典序)

题意  给你一些矩形框堆叠后的鸟瞰图  推断这些矩形框的堆叠顺序  每一个矩形框满足每边都至少有一个点可见  输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像  仅仅是这个要打印全部的可行方案  建图还是类似  由于每一个矩形框的四边都有点可见  所以每一个矩形框的左上角和右下角的坐标是能够确定的  然后一个矩形框上有其他字符时  就让这个矩形框相应的字符和那个其他字符建立一个小于关系  由于要打印方案  所以在有多个入度为0的点时须要用DFS对每种选择都进行一遍拓扑排序 #incl

[Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易可以想到一个做法,就是魔改迪杰斯特拉做法: 如果一个点可以更新到达其他点的距离,那个点的方案数就是这个点的方案数:如果一个点所更新出来的距离和之前的相等,那个点的方案数加等当前点的方案数. 用式子可以表现为: f[j]=f[i] (dis[j]>dis[i]+x)   f[j]+=f[i] (dis

POJ3249Test for Job(拓扑排序+DP)

题意就是给一个有向无环图,每个点都有一个权值,求从入度为0的点到出度为0点路径上经过点(包括起点终点)的权值和的最大值. 分析: 注意3点 1.本题有多组数据 2.可能有点的权值是负数,也就是结果可能为负,初值要设为负无穷. 3.入度或出度为0的点不止一个. 注意以上几点本题就很简单了,用到DP dis[i]:=max(dis[j],dis[i]+w[j])在拓扑排序过程同时进行即可. 考前练练拓扑排序和指针. 代码: program test; type point=^node; node=r

poj 3249 Test for Job 图上dp(记忆化搜索)

题意: 给一个n个点的DAG,每个点有一个值p,现在要在图上找一个入度为0到出度为0的路径,使路径上的点的p值和最大. 分析: dp[v]记录以点v为起点能获得的最大值,搜一遍即可. 代码: //poj 3249 //sep9 #include <iostream> using namespace std; const int maxN=100024; const int maxM=1000024; int n,m,e; int p[maxN],head[maxN],dp[maxN],vis[

POJ3249 Test for Job(拓扑排序+dp)

Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10137   Accepted: 2348 Description Mr.Dog was fired by his company. In order to support his family, he must find a new job as soon as possible. Nowadays, It's hard to have a jo

POJ 3648 Wedding(2-SAT 拓扑排序输出任意一种解决方案)

题目链接:http://poj.org/problem?id=3648 Description Up to thirty couples will attend a wedding feast, at which they will be seated on either side of a long table. The bride and groom sit at one end, opposite each other, and the bride wears an elaborate h

NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)

神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性,怎么办呢?拓扑排序. 把最短路上的点和零边的点拉出来跑拓扑排序,如果有零环的话必定度数不为0,而且要注意零环必须在<=最短路+k的路径上才输出-1,这个就用刚刚跑出来的1起点到n起点的最短路来判断就好了. 然后先按拓扑序DP出i相同的,然后再DP不在最短路上或者零边的. #include<iost

【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图

思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V',E')满足V'?V,E'是E中所有跟V'有关的边,则称G'是G的一个导出子图.若G'是G的导出子图,且G'半连通,则称G'为G的半连通子图.若G'是G所有半连通子图中包含节点数最多的,则称G'是G的最大半连通子图.给