分数规划。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 1050
#define maxe 10050
#define inf 2000000000
#define eps 1e-3
using namespace std;
int n,m,val[maxv],nume=,g[maxv],x,y,z,flag=;
struct edge
{
int v,c,nxt;
double w;
}e[maxe];
double dis[maxv];
bool vis[maxv];
void addedge(int u,int v,int c)
{
e[++nume].v=v;e[nume].c=c;
e[nume].nxt=g[u];g[u]=nume;
}
void rebuild(double x)
{
for (int i=;i<=nume;i++)
e[i].w=e[i].c*x-val[e[i].v];
}
void spfa(int x)
{
vis[x]=true;
for (int i=g[x];i;i=e[i].nxt)
{
int v=e[i].v;
if (dis[v]>dis[x]+e[i].w)
{
if (vis[v]) {flag=;break;}
else {dis[v]=dis[x]+e[i].w;spfa(v);}
}
}
vis[x]=false;
}
bool check(double x)
{
rebuild(x);
for (int i=;i<=n;i++) dis[i]=inf;
dis[]=-val[];flag=;spfa();
return flag;
}
void binary_search()
{
double l=,r=inf,ans;
while (r-l>=eps)
{
double mid=(l+r)/;
if (check(mid)) {ans=mid;l=mid;}
else r=mid;
}
printf("%.2lf\n",ans);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&val[i]);
for (int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
}
binary_search();
return ;
}