【题目】
题目背景:
蒟蒻 HansBug 在化学考场上,挠了无数次的头,可脑子里还是一片空白。
题目描述:
眼下出现在蒟蒻 HansBug 面前的是一个化学合成题,据他所知,一般答案如下面这样的格式:
(接下一行)
简单解释下:每种化合物可以通过一步反应生成另一个化合物(将这称作一步反应,设为 A—>B),现在假设每个 A—>B 中,理论上 1 1 1 个单位的 A 都仅可以生成 1 1 1 个单位的 B。然而实际实验表明,并不存在绝对完全的化学转化,设转化率为 C(即 1 1 1 个单位 A 实际可以生成 C 个单位的 B,0<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 1≤s,t≤n)
第 2 − m + 1 2-m+1 2−m+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—>3、1—>2、2—>3,产率分别为 0.8 0.8 0.8、 0.9 0.9 0.9、 0.9 0.9 0.9。
在样例 1 1 1 中,有两种可行的路线 1—>3 和 1—>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;
}