POJ 3249 Test for Job(拓扑排序+dp优化空间)

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 job, since there are swelling numbers of the unemployed. So some companies often use hard tests for their recruitment.

The test is like this: starting from a source-city, you may pass through some directed roads to reach another city. Each time you reach a city, you can earn some profit or pay some fee, Let this process continue until you reach a target-city. The boss will compute the expense you spent for your trip and the profit you have just obtained. Finally, he will decide whether you can be hired.

In order to get the job, Mr.Dog managed to obtain the knowledge of the net profit Vi of all cities he may reach (a negative Vi indicates that money is spent rather than gained) and the connection between cities. A city with no roads leading to it is a source-city and a city with no roads leading to other cities is a target-city. The mission of Mr.Dog is to start from a source-city and choose a route leading to a target-city through which he can get the maximum profit.

Input

The input file includes several test cases. 
The first line of each test case contains 2 integers n and m(1 ≤ n ≤ 100000, 0 ≤ m ≤ 1000000) indicating the number of cities and roads. 
The next n lines each contain a single integer. The ith line describes the net profit of the city iVi (0 ≤ |Vi| ≤ 20000) 
The next m lines each contain two integers xy indicating that there is a road leads from city x to city y. It is guaranteed that each road appears exactly once, and there is no way to return to a previous city. 

Output

The output file contains one line for each test cases, in which contains an integer indicating the maximum profit Dog is able to obtain (or the minimum expenditure to spend)

Sample Input

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

Sample Output

7

Hint

题意:给出n个点的权值和m条路径, 问一条路的最大权值是多少.
思路:原本思路是BFS枚举..然而MLE了,那么只能用dp来优化空间了。。两者都是枚举所有情况,前者将每次情况存入队列时容易因为图稠密而MLE;后者仅不断更新dp数组,在空间上节省了很多。
  1 #include "iostream"
  2 
  3 #include "cstdio"
  4 
  5 #include "cstring"
  6 
  7 #include "algorithm"
  8 
  9 #include "queue"
 10 
 11 #include "stack"
 12 
 13 #include "cmath"
 14 
 15 #include "utility"
 16 
 17 #include "map"
 18 
 19 #include "set"
 20 
 21 #include "vector"
 22 
 23 #include "list"
 24 
 25 #include "string"
 26 
 27 using namespace std;
 28 
 29 typedef long long ll;
 30 
 31 const int MOD = 1e9 + 7;
 32 
 33 const int INF = 0x3f3f3f3f;
 34 
 35 const int MAXN = 1e5 + 5;
 36 
 37 int n, m, num;
 38 
 39 int cost[MAXN], in[MAXN], out[MAXN], head[MAXN], dp[MAXN];
 40 
 41 bool vis[MAXN];
 42 
 43 struct node
 44 
 45 {
 46 
 47     /* data */
 48 
 49     int fr, to, nxt;
 50 
 51 }e[MAXN * 10];
 52 
 53 void add(int x, int y)
 54 
 55 {
 56 
 57     e[num].fr = x;
 58 
 59     e[num].to = y;
 60 
 61     e[num].nxt = head[x];
 62 
 63     head[x] = num++;
 64 
 65 }
 66 
 67 void toposort()
 68 
 69 {
 70 
 71     int cnt = 1;
 72 
 73     while(cnt < n) {
 74 
 75         for(int i = 1; i <= n; ++i)
 76 
 77             if(in[i] == 0 && !vis[i]) {
 78 
 79                 vis[i] = true;
 80 
 81                 cnt++;
 82 
 83                 for(int j = head[i]; j != -1; j = e[j].nxt) {
 84 
 85                     int x = e[j].to;
 86 
 87                     in[x]--;
 88 
 89                     if(dp[i] + cost[x] > dp[x]) dp[x] = dp[i] + cost[x];
 90 
 91                 }
 92 
 93             }
 94 
 95     }
 96 
 97 }
 98 
 99 int main(int argc, char const *argv[])
100 
101 {
102 
103     while(scanf("%d%d", &n, &m) != EOF) {
104 
105         memset(in, 0, sizeof(in));
106 
107         memset(out, 0, sizeof(out));
108 
109         memset(head, -1, sizeof(head));
110 
111         memset(vis, false, sizeof(vis));
112 
113         num = 1;
114 
115         for(int i = 1; i <= n; ++i)
116 
117             scanf("%d", &cost[i]);
118 
119         for(int i = 1; i <= m; ++i) {
120 
121             int x, y;
122 
123             scanf("%d%d", &x, &y);
124 
125             add(x, y);
126 
127             in[y]++;
128 
129             out[x]++;
130 
131         }
132 
133         for(int i = 1; i <= n; ++i)
134 
135             if(in[i] == 0) dp[i] = cost[i];
136 
137             else dp[i] = -INF;
138 
139         toposort();
140 
141         int ans = -INF;
142 
143         for(int i = 1; i <= n; ++i)
144 
145             if(out[i] == 0 && dp[i] > ans) ans = dp[i];
146 
147         printf("%d\n", ans);
148 
149     }
150 
151     return 0;
152 
153 }
View Code

代码转自(https://blog.csdn.net/gkhack/article/details/50223357)

 
posted @ 2018-08-02 20:46  llllrj  阅读(303)  评论(0编辑  收藏  举报