POJ 3621 Sightseeing Cows
来源:互联网 发布:微博刷转发软件 编辑:程序博客网 时间:2024/05/18 00:53
POJ 3621 Sightseeing Cows
图论,最优比率环路,01规划
传送门:POJ
题意
一群奶牛(奶牛。。。)要出去玩,一张无向图,每个点有欢乐值,每条边有路程。求一个旅行路线(环,从哪出发回到哪),每个地方可以走多次,但欢乐值只计算一次。使得总欢乐值/总路程 值最大。
思路
首先是01规划问题。01规划大概就是,给定两个数组,a[i]表示选取i的收益,b[i]表示选取i的代价。如果选取i,定义x[i]=1否则x[i]=0。每一个物品只有选或者不选两种方案,求一个选择方案使得
取得最值,即所有选择物品的总收益/总代价的值最大或是最小。最优比率环就是01规划的一种R=∑a[i]∗x[i]b[i]∗x[i] 传送门:Hhaile的专栏:01规划问题
设所求最值为ans,
即对于所有的环都有∑i=1nv[i]e[i]<=res
变形得∑i=1nv[i]<=res∗∑i=1ne[i]
再得临界条件是上式取等,res有最大值。即:随着k值变化,∑i=1n(res∗e[i]−v[i])>=0 ∑ni=1(k∗e[i]−v[i]) 值单调。该式另一个意思是是否存在负环,如果恒正,那么不存在负环;若可以取到负值,那么至少存在一个负环。所以二分答案,用spfa判断负环,使上式恰好取0的k值就是我们要的res。判断负环的方法:定义一个数组,表示出队次数。每次一个点出队更新别的点时,次数++。如果出队次数大于总点数,那么就存在负环。如果最后队列空了,就是求出了最短路,那么就不存在负环。
代码
有一点值得注意一下,我二分时左端点取0,右端点非常迷。最开始10007能过,变成1000倍1000000倍都过了,但是10,100,10000,100000倍就T了,不知道怎么回事
最后一列的代码长度,1599是对应右端点10007,1602是1000 0007,1607是1000 000 0007。为什么从1603直接到1606呢?因为数字后面加了ll。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAX_N=2007;const int MAX_M=10007;const double eps=1e-4;const int oo=1000000007;typedef long long LL;struct Graph{ int next; int to; int cost;}G[MAX_M];int head[MAX_M];int happy[MAX_N];int vis[MAX_N];double d[MAX_N];bool inque[MAX_N];bool spfa(int n,double ave){ for(int i=0;i<=n;i++) { d[i]=(double) oo; } memset(vis,0,sizeof(vis)); memset(inque,0,sizeof(inque)); queue<int> que; while(!que.empty()) que.pop(); d[1]=0.0;que.push(1);inque[1]=true; while(!que.empty()) { int cur=que.front();que.pop(); inque[cur]=false; vis[cur]++; if(vis[cur]>=n) return true; for(int i=head[cur];~i;i=G[i].next) { int to=G[i].to; if(d[to]>d[cur]+(double) G[i].cost*ave-(double) happy[cur]) { d[to]=d[cur]+(double) G[i].cost*ave-(double) happy[cur]; if(!inque[to]) { que.push(to); inque[to]=true; } } } } return false;}int main(){ int n,m; while(scanf("%d%d",&n,&m)==2) { memset(head,-1,sizeof(head)); memset(G,0,sizeof(G)); memset(happy,0,sizeof(happy)); for(int i=1;i<=n;i++) { scanf("%d",&(happy[i])); } for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); G[i].to=b;G[i].cost=c;G[i].next=head[a];head[a]=i; } double l=0.0,r=10007; while(r-l>eps) { double mid=(l+r)*(0.5); if(spfa(n,mid)) l=mid; else r=mid; } printf("%.2lf\n",l); } return 0;}
0 0
- POJ 3621 Sightseeing Cows
- poj 3621 Sightseeing Cows
- poj 3621 Sightseeing Cows
- poj 3621 Sightseeing Cows
- POJ 3621 Sightseeing Cows
- POJ 3621-- Sightseeing Cows
- 【POJ 3621】Sightseeing Cows
- POJ 3621 Sightseeing Cows
- poj 3621 Sightseeing cows
- POJ 3621 Sightseeing Cows 最优比率环
- POJ 题目3621 Sightseeing Cows(SPFA)
- POJ 3621 Sightseeing Cows 01分数规划
- POJ 3621 Sightseeing Cows 最优比率环
- Sightseeing Cows POJ
- POJ 3621 Sightseeing Cows(01分数规划)
- poj-3621-Sightseeing Cows-01分数规划+spfa判负环
- poj 3621 Sightseeing Cows(最优比率环)
- POJ 3621 Sightseeing Cows 最大密度环 01分数规划
- LNMP添加、删除虚拟主机及伪静态使用教程
- 小菜学习日记—html实现简单下拉二级菜单
- 花游双人、三级跳斩获金银
- 开始写博客了
- CString,string 和 Char*比较
- POJ 3621 Sightseeing Cows
- Hibernate初探之一对多映射(1)
- 解决WIN10下应用商店不能用,闪退的情况
- [林轩田]13-过拟合的危害
- 用Android自带的DrawerLayout和ActionBarDrawerToggle实现侧滑效果
- RedHat6.3(linux)编译Qt4.8.6中文不显示的解决方法
- struts2异常处理,global-results定义全局结果处理
- imag.js|教你如何智做原生APP
- Java中数组的扩容