POJ 3249 Test for Job
2014-06-03 23:30
302 查看
题目连接为:http://poj.org/problem?id=3249
大意如下:
给定n个城市,m个路径,每个城市有对应的收入(可能为负值)。起始城市(source-city)为入度为0的城市,目标城市(target-city)为出度为零的城市。
求出在给定的情况下,从起始城市到目标城市的最大收入。
思路:题目给出的图是DAG,所以对其进行拓扑排序,再利用动态规划方程:
dp[v]=max(dp[v],dp[u]+w[v]);
拓扑排序得到的是对图中的点的顺序。
拓扑排序的方法有两种:
一。记录所有点的入度和出度
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.(利用队列,将所有入度为0的点加入到队列中)
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.(邻接表中的每个点的入度减一,将删除的节点按照顺序放到数组中,或对点进行标号,这样形成的就是拓扑序)
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.(当队列为空时,完成对所有点的搜索)
本题的代码就是利用该方法得到拓扑序的。
二。利用DFS
反复利用DFS过程,直到所有点用完。 在DFS过程中,将完成搜索的点放到链表的头部(相当于栈的压栈操作)。
最后形成的链表就是有向图的拓扑序。
大意如下:
给定n个城市,m个路径,每个城市有对应的收入(可能为负值)。起始城市(source-city)为入度为0的城市,目标城市(target-city)为出度为零的城市。
求出在给定的情况下,从起始城市到目标城市的最大收入。
思路:题目给出的图是DAG,所以对其进行拓扑排序,再利用动态规划方程:
dp[v]=max(dp[v],dp[u]+w[v]);
拓扑排序得到的是对图中的点的顺序。
拓扑排序的方法有两种:
一。记录所有点的入度和出度
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.(利用队列,将所有入度为0的点加入到队列中)
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.(邻接表中的每个点的入度减一,将删除的节点按照顺序放到数组中,或对点进行标号,这样形成的就是拓扑序)
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.(当队列为空时,完成对所有点的搜索)
本题的代码就是利用该方法得到拓扑序的。
二。利用DFS
反复利用DFS过程,直到所有点用完。 在DFS过程中,将完成搜索的点放到链表的头部(相当于栈的压栈操作)。
最后形成的链表就是有向图的拓扑序。
#include <algorithm> #include <bitset> #include <deque> #include <functional> #include <fstream> #include <list> #include <iostream> #include <iomanip> #include <iterator> #include <map> #include <numeric> #include <queue> #include <set> #include <string> #include <stack> #include <sstream> #include <utility> #include <vector> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <climits> #define up(i, lower, upper) for(int i = lower; i < upper; i++) #define down(i, lower, upper) for(int i = upper-1; i >= lower; i--) using namespace std; #define MAX_N 100010 typedef pair<int, int> pii; typedef pair<double, double> pdd; typedef vector<int> vi; typedef vector<pii> vpii; typedef long long ll; typedef unsigned long long ull; const double pi = acos(-1.0); const double eps = 1.0e-9; template<class T> inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while ((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if (c == EOF) return false; if (c == '-') c = getchar(), tmp = -1; while (c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar(); n = x*tmp; return true; } template <class T> inline void write(T n) { if (n < 0) { putchar('-'); n = -n; } int len = 0, data[20]; while (n) { data[len++] = n % 10; n /= 10; } if (!len) data[len++] = 0; while (len--) putchar(data[len] + 48); } const int MAXN = 100001; int a[MAXN], ind[MAXN], outd[MAXN], dp[MAXN]; vector<int> e[MAXN]; queue<int> q; int main() { int n, m; while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; ++ i) { scanf("%d", &a[i]); e[i].clear(); dp[i] = INT_MIN; ind[i] = outd[i] = 0; } while (m --) { int x, y; scanf("%d%d", &x, &y); e[x].push_back(y); ++ ind[y]; ++ outd[x]; } for (int i = 1; i <= n; ++ i) if (!ind[i]) { dp[i] = a[i]; q.push(i); } while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = 0; i < e[cur].size(); ++ i) { dp[e[cur][i]] = max(dp[e[cur][i]], dp[cur] + a[e[cur][i]]); if (-- ind[e[cur][i]] == 0) q.push(e[cur][i]); } } int ans = INT_MIN; for (int i = 1; i <= n; ++ i) if (!outd[i]) ans = max(ans, dp[i]); printf("%d\n", ans); } return 0; }
相关文章推荐
- POJ 3249 Test for Job(拓扑排序)
- poj 3249 Test for Job
- POJ 3249 Test for Job 拓扑图DP
- poj 3249 Test for Job
- POJ 3249-Test for Job(拓扑排序&&DP)
- POJ 3249 Test for Job 解题报告 DP
- poj 3249 Test for Job (拓扑排序)
- poj3249 Test for Job --- 拓扑排序
- POJ - 3249 Test for Job (DAG+topsort)
- POJ 3249 Test for Job (记忆化搜索 好题)
- poj&nbsp;3249&nbsp;Test&nbsp;for&nbsp;Job&nbsp;dp(动态规…
- poj 3249 Test for Job 最长路
- poj 3249 Test for Job (记忆化深搜)
- POJ 3249 Test for Job
- POJ 3249 Test for Job
- POJ 3249 Test for Job(记忆化搜索)
- poj--3249 Test for Job(topsort + dp)
- POJ 3249 Test for Job 拓扑排序+DP
- POJ_3249 Test for Job(拓扑)
- POJ3249 Test for Job(记忆化搜索)