洛谷P2648 赚钱 题解(最短路变形)

洛谷P2648 赚钱

题目描述

zzy现在决定环游中国,顺便赚点钱。zzy在一个城市最多只能赚D元,然后他可以选择退休也就是停止赚钱,或者去其它城市工作。当然,他可以在别处工作一阵子后又回到原来的城市再赚D元。这样的往返次数是没有任何限制的。

城市间有P条单向路径连接,共有C座城市,编号从1到C。路径i从城市Ai到城市Bi,在路径行走上不用任何花费。

zzy还可以乘飞机从某个城市飞到另一个城市。共有F条单向的航线,第i条航线是从城市Ji飞到另一座城市Ki,费用是Ti元。假如zzy身上没有现钱,他可以用以后赚的钱来付机票钱。

zzy可以从任何一个城市出发开始赚钱,并且选择在任何时候、任何城市退休。现在zzy想要知道,如果在工作时间上不做限制,那么zzy共可以赚多少钱呢?如果赚的钱也不会出现限制,那么就输出orz。

输入格式

第一行,4个用空格分开的正整数,D,P,C,F。

第二行到P+1行,第i+1行包含2个用空格分开的整数,表示一条从城市Ai到城市Bi的单向路径。

接下来的F行,每行3个用空格分开的正整数,表示一条从城市Ji到城市Ki的单向航线,费用为Ti。

输出格式

如果zzy赚的钱没有限制,输出orz。如果有限制,那么就输出在给定的规则下zzy最多可以赚到的钱数。

输入输出样例

输入 #1

100 3 5 2
1 5
2 3
1 4
5 2 150
2 5 120

输出 #1

250

说明/提示

对于100%的数据,1<=D<=1000,1<=P<=200,2<=C<=300,1<=F<=400。

解题思路

简单理解一下题目,每个点都有一个值(赚的钱D),有P个免费道路,还有F个飞机航线。问我们最多可以赚多少钱,如果不受时间限制的话,可以一直赚钱,那就输出“orz”,一直赚钱的话,很可能就是出现了环。

所以,我们可以把每个点的值下放到连接的边上,也就是说,把免费的道路变成能给你钱的道路,把飞机航线变成赚到的钱减去机票钱后得到的价格。这样,我们就把杂乱的点权和边权,全部变成了边权,题目要求我们求出最多能赚多少钱,因为可以从任意一个点开始,所以是多源最长路问题,我们用floyd解决。

这里要特殊注意,出现环的情况,我们可以跑两次最长路,看结果是否相同,不相同就证明有环,可以一直赚钱。否则直接输出就可以了。

代码示例

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int d,p,c,f;
int g[310][310];

void floyd(){
	for(int k=1;k<=c;k++){
		for(int i=1;i<=c;i++){
			for(int j=1;j<=c;j++){
				g[i][j]=max(g[i][j],g[i][k]+g[k][j]);
			}
		}
	}
}

int find(){
	int x=0;
	for(int i=1;i<=c;i++)
		for(int j=1;j<=c;j++)
			x=max(x,g[i][j]);
	return x;
}

int main(){
	cin>>d>>p>>c>>f;
	memset(g,200,sizeof(g));
	int x,y,z;
	for(int i=1;i<=p;i++){
		cin>>x>>y;
		g[x][y]=d;
	}
	for(int i=1;i<=f;i++){
		cin>>x>>y>>z;
		g[x][y]=d-z;
	}
	floyd();
	int ans1=find();
	floyd();
	int ans2=find();
	if(ans1!=ans2) cout<<"orz"<<endl;
	else cout<<ans1+d<<endl;
	return 0;
}

当然,你如果想从每个点跑一次spfa也可以(数据比较和善) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值