POJ3621
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=5100;
const double eps=1e-5;
int head[maxn],ver[maxn],nt[maxn],edge[maxn];
bool ha[maxn];
int tot=0,cnt=0;
double d[maxn];
int hh[maxn];
int many[maxn];
int si[maxn];
int n,m;
void init(void)
{
tot=cnt=0;
memset(head,0,sizeof(head));
memset(ha,0,sizeof(ha));
}
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z;
nt[tot]=head[x],head[x]=tot;
}
void dfs(int x)
{
ha[x]=true;
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(ha[y]) continue;
dfs(y);
}
return ;
}
bool spfa(double mid)
{
for(int i=1;i<=n;i++)
{
si[i]=0;
d[i]=1e18;
ha[i]=false;
}
queue<int>q;
for(int i=1;i<=cnt;i++)
{
q.push(many[i]);
ha[many[i]]=true;
si[many[i]]++;
d[many[i]]=0.0;
}
while(q.size())
{
int x=q.front();
q.pop();
ha[x]=false;
for(int i=head[x];i;i=nt[i])
{
int y=ver[i],z=edge[i];
double kk=-hh[x]*1.0+mid*z;
if(d[y]>d[x]+kk)
{
d[y]=d[x]+kk;
if(!ha[y])
{
q.push(y);
ha[y]=true;
si[y]++;
if(si[y]>=n) return true;
}
}
}
}
return false;
}
int main(void)
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=1;i<=n;i++)
scanf("%d",&hh[i]);
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for(int i=1;i<=n;i++)
{
if(!ha[i])
{
many[++cnt]=i;
dfs(i);
}
}
double l=0.0,r=1e6+10;
double mid;
while(r-l>eps)
{
mid=(r+l)/2;
if(spfa(mid)) l=mid;
else r=mid;
}
printf("%.2f\n",(l+r)/2);
}
return 0;
}