Http://poj.org/problem? Id = 3621
A directed graph is given. Each vertex has a vertex weight, and each directed edge has an edge weight, A ring is required to maximize the ratio of the sum of vertices in the ring to the sum of edge weights.
Idea: similar to the optimal rate spanning tree.Set the vertex right to v [I] And the edge right to e [I]. The difference is that one is a vertex and the other is an edge. How can we put these two values together like a spanning tree? They can all be converted to the edge. In the same divisor, each time an edge is re-authorized to v [I]-λ * e [I] (v [I] is the vertex right of the edge end point ). Because the maximum ratio is required, all loops in the graph are <= 0 under this premise. Therefore, we only need to judge whether there is a positive ring each time spfa. If yes, it indicates that λ is too small; otherwise, λ is too large. In fact, the weight of each edge is the negative value of the above (v [I]-λ * e [I]), and then the spfa can determine the negative ring. After trying, the time is almost the same. The following code identifies a negative ring.
#include
#include
#include #include
#include
#include
#include
#include
#include
#include
#define LL long long#define _LL __int64#define eps 1e-7using namespace std;const _LL INF = 1e18;const int maxn = 1010;struct node{int v;double w;};vector
edge[maxn];int Map[maxn][maxn];int fun[maxn];int n,m;bool spfa(double mid){queue
que;while(!que.empty()) que.pop();int inque[maxn],in[maxn];double dis[maxn];memset(inque,0,sizeof(inque));memset(in,0,sizeof(in));for(int i = 1; i <= n; i++){que.push(i);dis[i] = 0;in[i] = 1;inque[i] = 1;}while(!que.empty()){int u = que.front();que.pop();inque[u] = 0;for(int i = 0; i < (int)edge[u].size(); i++){int v = edge[u][i].v;double w = edge[u][i].w * mid - fun[v];if(dis[v] > dis[u] + w){dis[v] = dis[u] + w;if(!inque[v]){inque[v] = 1;que.push(v);in[v]++;if(in[v] > n)return true;}}}}return false;}int main(){while(~scanf("%d %d",&n,&m)){int u,v,w;for(int i = 1; i <= n; i++)edge[i].clear();for(int i = 1; i <= n; i++)scanf("%d",&fun[i]);for(int i = 1; i <= m; i++){scanf("%d %d %d",&u,&v,&w);Map[u][v] = w;edge[u].push_back((struct node){v,w});}double l = 0.0, r = 1000.0;double mid;while(fabs(r-l) > eps){mid = (l+r)/2;if(spfa(mid))l = mid;else r = mid;}printf("%.2f\n",l);}return 0;}