【洛谷】P1073 [NOIP2009 提高组] 最优贸易(dp+搜索)


接下来讲具体解法。

第一、输入。存邻接表

第二、我们需要做深搜。可以用递归来做,同时做动规:

函数如下(贴了注释).

void dfs(int x,int minx,int pre) {                           //x表示当前访问的节点编号,minx表示目前为止的最小的商品价格,pre表示上一个节点的编号
    int flag=1;                                          //用于判断是否已被访问过,需要终止
    minx=min(c[x],minx);                                 //判断本次的商品价格是否是最小值
    if (mi[x]>minx) mi[x]=minx,flag=0;                   //判断mi数组(记录了每次的最小值)并更新,在更新的同时把flag设为0(不用退出了)
    做动态规划;                                         //别着急flag还会继续更新的
    if (flag) return;                                    //退出,千万不能露,不然程序就会放飞自我,堆栈溢出->完美MLE只有10分。
    for (int i=0;i<g[x].size();i++) dfs(g[x][i],minx,x); //继续进行递归调用,访问目前节点能访问到的节点。
}

 

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x7f7f7f7f
const int N=1e5+10;
vector<int>v[N];
int n,m,f[N],mi[N],c[N];
void init(){
	for(int i=1;i<=n;i++)mi[i]=inf;
}
void dfs(int x,int minx,int pre){
	int flag=1;
	minx=min(c[x],minx);
	if(mi[x]>minx){
		mi[x]=minx;
		flag=0;
	}
	int mmax=max(f[pre],c[x]-minx);
	if(f[x]<mmax){
		f[x]=mmax;
		flag=0;
	}
	if(flag)return;
   for(auto i:v[x]){
   	dfs(i,minx,x);
   } 
}
void solve() {
   cin>>n>>m;
   init();
   for(int i=1;i<=n;i++) cin>>c[i];
   for(int i=1;i<=m;i++){
   	int x,y,z;
   	cin>>x>>y>>z;
   	v[x].push_back(y);
   	if(z==2) v[y].push_back(x);
   }
   dfs(1,inf,0);
   cout<<f[n]<<"\n";
   
}
signed main() {

	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int tt=1;
	//cin>>tt;
	while(tt--) {
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值