您的位置:首页 > 其它

POJ 3249 Test for Job(DAG上的dp + 记忆化搜索)

2017-02-23 17:48 411 查看
题意:出发点(入度为0),终点(出度为0),都可能不止一个;求从出发点到目标点的最大收获或最少消费(有些城市值为负,表示消费)

思路:记忆化搜索避免超时。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define INF 2147483647
const int maxn=1e5+10;
int v[maxn]; //保存值
int d[maxn]; //用于记忆化搜索
int root[maxn]; //统计入度
int n,m;
vector<int>vec[maxn];
int dp(int i){
int&ans=d[i];
if(ans!=0)return ans;
int len=vec[i].size();
if(len==0)return v[i];
ans=-INF;
for(int j=0;j<len;j++)
ans=max(ans,dp(vec[i][j])+v[i]);
return ans;
}
int main(){
while(scanf("%d%d",&n,&m)==2){
memset(d,0,sizeof(d));
memset(root,0,sizeof(root));
for(int i=1;i<=n;i++)scanf("%d",&v[i]);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
vec[a].push_back(b);
root[b]++;
}
int ans=-INF;
for(int i=1;i<=n;i++){
if(!root[i]) //刚开始没用这个判断,当所有点的值大于0时没问题,小于0就会出问题了
ans=max(ans,dp(i));
}
printf("%d\n",ans);
for(int i=1;i<=n;i++)
vec[i].clear();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: