The general idea is to find a ring that maximizes the ratio of the sum of vertex weights to the sum of edge weights.
First of all, you must note that the question requirements can start from any point. Many online problem solving reports start from by default. Although this problem has passed, it is obviously not correct.
Because the question is max, after the Edge Weight deformation, use SPFA to find the longest path, to see if there is a positive ring, and then perform a binary search based on this.
If you don't know how the graph is built, you can see how the 01 plan is made.
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <cstdlib>
# Include <cstdio>
# Include <queue>
# Define maxn1005
# Define MAXM 50005
# Define INF 1000000000
# Define eps 1e-6
Using namespace std;
Struct node
{
Int v, next;
Double w;
} Edge [MAXM];
Int head [MAXN], e, vis [MAXN], q [50 * MAXM], c [MAXN];
Int n, m;
Double d [MAXN], val [MAXN];
Void insert (int x, int y, double w)
{Www.2cto.com
Edge [e]. v = y;
Edge [e]. w = w;
Edge [e]. next = head [x];
Head [x] = e ++;
}
Bool spfa (double mid)
{
Int h = 0, t = 0;
For (int I = 1; I <= n; I ++)
{
Vis [I] = c [I] = 1;
Q [t ++] = I;
D [I] = 0;
}
While (h <t)
{
Int u = q [h ++];
Vis [u] = 0;
For (int I = head [u]; I! =-1; I = edge [I]. next)
{
Int v = edge [I]. v;
Double w = val [u]-mid * edge [I]. w;
If (d [v] <d [u] + w)
{
D [v] = d [u] + w;
If (! Vis [v])
{
Q [t ++] = v;
Vis [v] = 1;
C [v] ++;
If (c [v]> n) return 1;
}
}
}
}
Return 0;
}
Int main ()
{
Int x, y;
Double w;
E = 0;
Memset (head,-1, sizeof (head ));
Scanf ("% d", & n, & m );
For (int I = 1; I <= n; I ++) scanf ("% lf", & val [I]);
For (int I = 1; I <= m; I ++)
{
Scanf ("% d % lf", & x, & y, & w );
Insert (x, y, w );
}
Double low = 0, high = 1000;
While (high-low> eps)
{
Double mid = (low + high)/2;
If (spfa (mid) low = mid;
Else high = mid;
}
Printf ("%. 2f \ n", low );
Return 0;
}
Author: sdj222555