1 /*Author:WNJXYK*/
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6
7 int l,p;
8
9 struct Edge{
10 int v;
11 double t;
12 int f;
13 int nxt;
14 Edge(){}
15 Edge(int a,int b,int c){
16 v=a;f=b;nxt=c;
17 }
18 };
19 Edge e[6000];
20 int nume;
21 int head[1010];
22 int val[1010];
23 inline void addSingleEdge(int x,int y,int w){
24 e[++nume]=Edge(y,w,head[x]);
25 head[x]=nume;
26 }
27 inline void addEdge(int x,int y,int w){
28 addSingleEdge(x,y,w);
29 addSingleEdge(y,x,w);
30 }
31
32 queue<int> que;
33 double dist[1010];
34 bool inque[1010];
35 bool visited[1010];
36 int intime[1010];
37
38 inline bool spfa(int src){
39 bool isPrint=false;
40 while(!que.empty()) que.pop();
41 memset(dist,127/3,sizeof(dist));
42 memset(inque,false,sizeof(inque));
43 memset(intime,0,sizeof(intime));
44 que.push(src);
45 dist[src]=0;
46 inque[src]=true;
47 intime[src]++;
48 visited[src]=true;
49 while(!que.empty()){
50 int now=que.front();
51 que.pop();
52 for (int i=head[now];i;i=e[i].nxt){
53 int v=e[i].v;double w=e[i].t;
54 if (dist[v]>dist[now]+w){
55 intime[v]++;
56 if (intime[v]>l){
57 return true;
58 }
59 dist[v]=dist[now]+w;
60 if (!inque[v]){
61 visited[v]=true;
62 inque[v]=true;
63 que.push(v);
64 }
65 }
66 }
67 if (isPrint) break;
68 inque[now]=false;
69 }
70 return false;
71 }
72
73 inline bool check(double x){
74 memset(visited,false,sizeof(visited));
75 for (int i=1;i<=nume;i++) e[i].t=x*(double)e[i].f-val[e[i].v];
76 for (int i=1;i<=l;i++) if (!visited[i]) if (spfa(i)) return true;
77 return false;
78 }
79
80 int main(){
81 scanf("%d%d",&l,&p);
82 for (int i=1;i<=l;i++){
83 scanf("%d",&val[i]);
84 }
85 for (int i=1;i<=p;i++){
86 int x,y,t;
87 scanf("%d%d%d",&x,&y,&t);
88 addSingleEdge(x,y,t);
89 }
90 double left=0,right=10000,mid;
91 while(left+0.001<=right){
92 mid=(left+right)/2;
93 //printf("%.2lf\n",mid);
94 if (check(mid)==false){
95 right=mid;
96 }else{
97 left=mid;
98 }
99 }
100 printf("%.2lf\n",left);
101 return 0;
102 }