POJ 3249 Test for Job(记忆化搜索)

题意:给定一个有向无环图,每个结点有权值,从入度为零的点作为起点,出度为零的点作为终点,要求出到终点时可能的最大权值(权值可能为负数,不过都不超过int)

思路:记忆化搜索,很多人反向建图来做,不知道有什么好处。我还是正常顺序。事先记录好各点的入度,枚举这些点搜索出的可能最大权值。

这种题目的状态转移方程还是很好分析的dp[i] = v[i] + max(dp[u0],dp[u1],......,dp[un]);  u0--un为i连接的结点。此外点过多,用邻接表存储。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <cmath>
#define MAX 111111
#define INF 0x7FFFFFFF
using namespace std;

vector<int> edge[MAX];
int v[MAX],dp[MAX],deg[MAX];
int n,m;

void init() {
    for(int i=0; i<=MAX; i++) {
        dp[i] = -INF;
        edge[i].clear();
    }
    memset(deg,0,sizeof(deg));
}

int dfs(int v0) {
    if(dp[v0] != -INF) return dp[v0];
    int size = edge[v0].size();
    if(size == 0) return v[v0];
    int maxx = -INF;
    for(int i=0; i<size; i++) {
        int u = edge[v0][i];
        maxx = max(maxx,dfs(u));
    }
    return dp[v0] = v[v0] + maxx;
}

int main() {
    int i,j,a,b;
    while(scanf("%d%d",&n,&m) != EOF) {
        init();
        for(i=1; i<=n; i++) {
            scanf("%d",&v[i]);
        }
        for(i=1; i<=m; i++) {
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
            deg[b] ++;
        }
        int maxx = -INF;
        for(i=1; i<=n; i++) {
            if(!deg[i]) {
                maxx = max(maxx,dfs(i));
            }
        }
        printf("%d\n",maxx);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值