您的位置:首页 > 其它

POJ 3249 Test for Job 拓扑排序+DP

2014-08-04 21:11 295 查看
http://poj.org/problem?id=3249

题意:

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

分析:

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

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

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int n, m, esize, x, y;
int a[100100], en[100100], in[100100], bfn[100100], dp[100100];
bool ed[100100];
struct edge{
int v, n;
} e[1000100];
void addedge(int u, int v)
{
e[esize].v = v;;
e[esize].n = en[u];
en[u] = esize ++;
}
queue<int> q;
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i++)
scanf("%d", a+i);
memset(en, -1, sizeof(en));
memset(in, 0, sizeof(0));
memset(ed, true, sizeof(ed));
esize = 0;
for (int i = 0; i < m; i++){
scanf("%d %d", &x, &y);
addedge(x, y);
in[y]++;
ed[x] = 0;
}
for (int i = 1; i <= n; i++)
if (!in[i]) q.push(i);
int ans = -2147483640;
int cnt = 0;
while(!q.empty())
{
int u = q.front(); q.pop();
bfn[cnt++] = u;
for (int t = en[u]; t != -1; t = e[t].n){
int v = e[t].v;
in[v] --;
if (in[v] == 0)    q.push(v);
}
}
memset(dp, -1, sizeof(dp));
for (int i = 0; i < n; i++){
int u = bfn[i];
if (dp[u] == -1) dp[u] = a[u];
if (ed[u]) ans = max(ans, dp[u]);
for (int t = en[u]; t != -1; t = e[t].n){
int v = e[t].v;
if (dp[v] == -1 || dp[v] < dp[u] + a[v])
dp[v] = dp[u] + a[v];
}
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: