C 国里一共有 N 个城镇,编号为 1 到 N 。其中第 i 个城镇与第 i + 1 个城镇连接着一条收费为 c i 的从
i 到 i + 1 的单向道路 (1 ≤ i < n)。现在,杰杰作为一个旅行者,他的任务就是从第 1 个城镇出发,到达编
号为 N 的城镇。他觉得这样会很无聊,海克斯科技公司也是这么认为的。所以该公司在若干个城镇里设置了
共 M 个单向传送门。每个传送门有 4 个参数 s t p w。s 表示传送门的出发城镇,t 表示传送门的传送目标城
镇,保证 t 大于 s,w 表示使用该传送门的花费,p 为传送成功的概率,若传送失败会自动返回出发的城市而
且该传送门会永久损坏;而且无论传送成功与否,只要使用了该传送门就得花费 w。现在,杰杰正在规划他
的旅行方案。请你帮他规划一条最优策略,使得旅途期望花费最小。
懒癌发作了……
随便列个式子然后贪心一波就好了……
#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef double db;
const int maxn=100000+10;
int e[maxn],h[maxn],go[maxn*2],dis[maxn*2],next[maxn*2],id[maxn];
bool bz[maxn];
db pp[maxn*2];
db f[maxn],p[maxn],w[maxn],x[maxn],y[maxn];
int i,j,k,l,t,n,m,tot;
db zlt;
void add(int x,int y,int c,db z){
go[++tot]=y;
dis[tot]=c;
pp[tot]=z;
next[tot]=h[x];
h[x]=tot;
}
bool cmp(int a,int b){
if (y[a]==1) return 1;
else if (y[b]==1) return 0;
else return x[a]/(1-y[a])<x[b]/(1-y[b]);
}
void solve(int now){
if (bz[now]) return;
bz[now]=1;
int i;
int t=h[now],top=0;
while (t){
solve(go[t]);
t=next[t];
}
t=h[now];
while (t){
e[++top]=go[t];
w[top]=dis[t];
p[top]=pp[t];
x[top]=f[e[top]]*p[top]+w[top];
y[top]=1-p[top];
id[top]=top;
t=next[t];
}
sort(id+1,id+top+1,cmp);
db r=1;
fo(i,1,top){
f[now]=f[now]+r*x[id[i]];
r=r*(1-p[id[i]]);
}
}
int main(){
scanf("%d%d",&n,&m);
fo(i,1,n-1){
scanf("%d",&j);
add(i,i+1,j,1);
}
fo(i,1,m){
scanf("%d%d%lf%d",&j,&k,&zlt,&l);
add(j,k,l,zlt);
}
solve(1);
printf("%.2lf\n",f[1]);
}