【洛谷 2784】化学1(chem1)- 化学合成

【题目】

传送门

题目背景:

蒟蒻 HansBug 在化学考场上,挠了无数次的头,可脑子里还是一片空白。

题目描述:

眼下出现在蒟蒻 HansBug 面前的是一个化学合成题,据他所知,一般答案如下面这样的格式:

在这里插入图片描述 (接下一行)
在这里插入图片描述

简单解释下:每种化合物可以通过一步反应生成另一个化合物(将这称作一步反应,设为 A—>B),现在假设每个 A—>B 中,理论上 1 1 1 个单位的 A 都仅可以生成 1 1 1 个单位的 B。然而实际实验表明,并不存在绝对完全的化学转化,设转化率为 C(即 1 1 1 个单位 A 实际可以生成 C 个单位的 B0<C<1)。

现在蒟蒻 HansBug 的知识体系中有 n n n 个这样 A—>B 的转化。然而题目中蒟蒻 HansBug 要由 1 1 1 个单位的化合物 s s s 生成化合物 t t t,可是他脑细胞和 RP 已经消耗殆尽,所以找到最终产量最高的合成路线的艰巨任务就交给你啦!

输入格式:

第一行为 4 4 4 个整数: n n n m m m s s s t t t,分别表示总共出现的化合物个数、HansBug 所知道的反应个数、起始的化合物序号、终末的化合物序号。( 1 ≤ s , t ≤ n 1\le s,t\le n 1s,tn

2 − m + 1 2-m+1 2m+1 行每行为两个整数和一个实数: a i a_i ai b i b_i bi c i c_i ci,分别表示第 i i i 个反应为由 1 1 1 个单位的 a i a_i ai 化合物生成 c i c_i ci 单位的 b i b_i bi 化合物。

输出格式:

一行,包含一个实数,为最佳路线下最终的产量(四舍五入保留 4 4 4 位小数),如果没有可行路线的话,输出 orz

样例数据:

【样例 1 1 1

输入
3 3 1 3
1 3 0.8
1 2 0.9
2 3 0.9

输出
0.8100

【样例 2 2 2

输入
3 3 2 1
1 3 0.8
1 2 0.9
2 3 0.9

输出
orz

说明:

样例 1 1 1 和样例 2 2 2 中,两条合成路线分别为 1—>31—>22—>3,产率分别为 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9 0.9

在样例 1 1 1 中,有两种可行的路线 1—>31—>2—>3,最终产量分别为 0.8 0.8 0.8 0.9 × 0.9 = 0.81 0.9\times0.9=0.81 0.9×0.9=0.81,故第二条路线更优,产量为 0.8100 0.8100 0.8100

样例 2 2 2 中, 2 2 2 只能生成 3 3 3 3 3 3 无法生成别的化合物,故无法生成,蒟蒻 HansBug 只好选择 orz

数据范围:
在这里插入图片描述


【分析】

很简单的一道题啦

d i j k s t r a dijkstra dijkstra 求最短路就可以了


【代码】

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5005
#define M 2000005
using namespace std;
int n,m,s,t,num;
int first[N],v[M],nxt[M];
double w[M],d[N];
priority_queue<pair<double,int> >q;
void add(int x,int y,double z)
{
	nxt[++num]=first[x];
	first[x]=num,v[num]=y,w[num]=z;
}
void dijkstra(int s)
{
	int x,y,i;
	memset(d,0,sizeof(d));
	q.push(make_pair(1,s));d[s]=1;
	while(!q.empty())
	{
		x=q.top().second,q.pop();
		for(i=first[x];i;i=nxt[i])
		{
			y=v[i];
			if(d[y]<d[x]*w[i])
			{
				d[y]=d[x]*w[i];
				q.push(make_pair(d[y],y));
			}
		}
	}
}
int main()
{
	int x,y,i;double z;
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(i=1;i<=m;++i)
	{
		scanf("%d%d%lf",&x,&y,&z);
		add(x,y,z);
	}
	dijkstra(s);
	if(d[t]==0)  puts("orz");
	else  printf("%.4lf",d[t]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值