POJ3621 Sightseeing Cows(最优比率环)

来源:互联网 发布:用手机装修淘宝店铺 编辑:程序博客网 时间:2024/04/30 00:45

题目链接:http://poj.org/problem?id=3621

在一个有向图中选一个环,使得环上的点权和除以边权和最大,求这个比值。

经典的分数规划问题,我觉得这两篇题解写得很清楚,可以参考一下http://blog.csdn.net/gengmingrui/article/details/47443705http://blog.csdn.net/wall_f/article/details/8221807

个人觉得01分数规划几乎都是二分或者迭代比值,从而找到一个最优解,使得原来的函数值等于0

#include<cstdio>#include<cstring>#include<queue>#define eps 1e-3#define MAXN 1010using namespace std;struct T{int v;int w;int next;}edge[5005];int cnt,head[MAXN];void add_edge(int u,int v,int w){edge[cnt].v = v;edge[cnt].w = w;edge[cnt].next = head[u];head[u] = cnt++;}int n,m;int w[MAXN];double dis[MAXN];bool inque[MAXN];int vis[MAXN];bool SPFA(double R)//SPFA判断负权环{queue<int> myque;memset(inque,0,sizeof inque);memset(vis,0,sizeof vis);for(int i = 1; i <= n; i++)dis[i] = 1e15;myque.push(1);dis[1] = 0;inque[1] = 1;vis[1]++;while(!myque.empty()){int u = myque.front();myque.pop();inque[u] = 0;for(int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].v;int y = edge[i].w;if(dis[u] + R*y - w[u] < dis[v]){dis[v] = dis[u] + R*y - w[u];if(!inque[v]){myque.push(v);inque[v] = 1;vis[v]++;if(vis[v] > n) return 1;}}}}return 0;}int main(){memset(head,-1,sizeof head);scanf("%d%d",&n,&m);for(int i = 1; i <= n; i++)scanf("%d",&w[i]);for(int i = 1; i <= m; i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);add_edge(a,b,c);}double l = 0,r = 10000,mid;while(r - l > eps){mid = (l+r)/2;if(SPFA(mid)) l = mid;//由于我们是把权值取反了的,因此题解中的R过大变成了R过小else r = mid;}printf("%.2lf\n",l);return 0;}


0 0
原创粉丝点击