abc188E- Peddler(DAG)

   日期:2021-01-12     浏览:100    评论:0    
核心提示:题目大意:n个点,m条边在n个点有一个物品买入和卖出的价值m条边中保证x<y(连接的两个点)问 对一个物品买卖一次的最大利润是多少Solution 1:因为边中保证了x<y,所以可以看出有向无环图mi[]定义为到达i点之前(不包括i点)的最小出买卖值那么如果在i点进行交易的话,得到的利润为 val[i] - mi[i]只需要枚举每个点 更新答案然后用每个点的边集再更新一边 mi数组复杂度O(N+M)Solution 2:如果题目的边中不保证x<y,是一个普通的有

题目大意:

n个点,m条边
在n个点有一个物品买入和卖出的价值
m条边中保证x<y(连接的两个点)
问 对一个物品买卖一次的最大利润是多少

Solution 1:

因为边中保证了x<y,所以可以看出有向无环图
mi[]定义为到达i点之前(不包括i点)的最小出买卖值
那么如果在i点进行交易的话,得到的利润为 val[i] - mi[i]
只需要枚举每个点 更新答案
然后用每个点的边集再更新一边 mi数组
复杂度O(N+M)

Solution 2:

如果题目的边中不保证x<y,是一个普通的有向图

对所有的点的买卖价值升序排列
选最便宜的点,然后进行bfs列举他能够到达的所有点
更新答案
ans = max(ans,val[u]-minn1)
然后选第二便宜的点
重复上述操作

走过的点可以不用再走
因为先选的minn1 所能够达到的点
如果minn2所能够到达的点中和minn1到达的点中有相同的点,那么一定是minn1更优
所以minn2的再次经过时可以忽略

Code1:

ll n,m,val[maxn];
vector<ll>e[maxn];
ll ans=-inf,mi[maxn];
int main() { 
	n=read(),m=read();
	rep(i,1,n) val[i] = read(),mi[i] = inf;
	for(int i=1 ; i<=m ; i++) { 
		int u,v;
		u=read(),v=read();
		e[u].push_back(v);
	}
	for(int i=1 ; i<=n ; i++) { 
		ans = max(ans,val[i] - mi[i]);
		mi[i] = min(mi[i],val[i]);
		for(int j:e[i]) { 
			mi[j]  = min(mi[j],mi[i]);
		}
	}
	out(ans);
	return 0;
}

Code2:

int n,m,ans=-inf,vis[maxn],val[maxn];
vector<int>e[maxn];
struct node { 
	int num,id;
} a[maxn];
bool cmp(node x,node y) { 
	return x.num<y.num;
}
void bfs(int st) { 
	queue<int>q;
	q.push(a[st].id);
	while(q.size()) { 
		int fr =q.front();
		q.pop();
		for(int v:e[fr]) { 
			if(vis[v]) continue;
			vis[v]=1;
			ans = max(ans,val[v] - a[st].num);
			q.push(v);
		}
	}
}
int main() { 
	n=read(),m=read();
	for(int i=1 ; i<=n ; i++) { 
		a[i].id = i;
		val[i] = a[i].num = read();
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1 ; i<=m ; i++) { 
		int u,v;
		u=read(),v=read();
		e[u].push_back(v);
	}
	for(int i=1 ; i<=n ; i++) { 
		if(vis[i]) continue;
		bfs(i);
	}
	out(ans);
	return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服