http://poj.org/problem?id=3621

求一个环的{点权和}除以{边权和},使得那个环在所有环中{点权和}除以{边权和}最大。

0/1整数划分问题

令在一个环里,点权为v[i],对应的边权为e[i], 

即要求:∑(i=1,n)v[i]/∑(i=1,n)e[i]最大的环(n为环的点数), 

设题目答案为ans, 

即对于所有的环都有 ∑(i=1,n)(v[i])/∑(i=1,n)(e[i])<=ans 

变形得ans* ∑(i=1,n)(e[i])>=∑(i=1,n)(v[i]) 

再得 ∑(i=1,n)(ans*e[i]-v[i]) >=0 

稍分析一下,就有: 

当k<ans时,就存在至少一个环∑(i=1,n)(k*e[i]-v[i])<0,即有负权回路(边权为k*e[i]-v[i]); 

当k>=ans时,就对于所有的环∑(i=1,n)(k*e[i]-v[i])>=0,即没有负权回路。 

然后我们就可以使新的边权为k*e[i]-v[i],用spfa来判断负权回路,二分ans。

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <queue>
  5. #include <cstring>
  6. #include <algorithm>
  7. #define RD(x) scanf("%d",&x)
  8. #define RD2(x,y) scanf("%d%d",&x,&y)
  9. #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
  10. #define clr0(x) memset(x,0,sizeof(x))
  11. #define clr1(x) memset(x,-1,sizeof(x))
  12. using namespace std;
  13. typedef long long LL;
  14. const int maxn = 1005,maxm = 105;
  15. const double eps = 1e-3;
  16. const int inf = 0x7fffffff;
  17. int v[maxn];
  18. struct edge{
  19. int v,w,next;
  20. edge(){};
  21. edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
  22. }e[maxn*5];
  23. int head[maxn],vis[maxn],_v[maxn],cnt[maxn],ecnt,n,m;
  24. double dist[maxn];
  25. void add(int u,int v,int w)
  26. {
  27. e[ecnt] = edge(v,w,head[u]);
  28. head[u] = ecnt++;
  29. }
  30. void init()
  31. {
  32. for(int i = 1;i <= n;++i)
  33. RD(_v[i]);
  34. ecnt = 0;
  35. clr1(head);//判负环的初始化
  36. int u,v,w;
  37. while(m--){
  38. RD3(u,v,w);
  39. add(u,v,w);
  40. }
  41. return ;
  42. }
  43. bool spfa(double mid)
  44. {
  45. clr0(vis),clr0(cnt);
  46. fill(dist,dist + n + 1,inf);
  47. dist[1] = 0;
  48. queue<int> q;
  49. q.push(1);
  50. while(!q.empty()){
  51. int u = q.front();
  52. q.pop();
  53. vis[u] = false;
  54. cnt[u]++;
  55. if(cnt[u] > n)
  56. return true;
  57. for(int i = head[u];i != -1;i = e[i].next){
  58. int v = e[i].v;
  59. double tmp = mid*e[i].w - _v[v];//"边权"
  60. if(dist[u] + tmp < dist[v]){
  61. dist[v] = dist[u] + tmp;
  62. if(!vis[v]){
  63. vis[v] = true;
  64. q.push(v);
  65. }
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. void work()
  72. {
  73. double l = 0,r = 10000,mid,ans;
  74. while(r - l > eps){
  75. mid = (l + r)/2;
  76. if(spfa(mid)){
  77. ans = mid;
  78. l = mid - 0.000001;
  79. }else
  80. r = mid + 0.000001;
  81. }
  82. printf("%.2f\n",ans);
  83. }
  84. int main()
  85. {
  86. while(~RD2(n,m)){
  87. init();
  88. work();
  89. }
  90. return 0;
  91. }

poj 3621 二分+spfa判负环的更多相关文章

  1. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

  2. POJ 3259 Wormholes(SPFA判负环)

    题目链接:http://poj.org/problem?id=3259 题目大意是给你n个点,m条双向边,w条负权单向边.问你是否有负环(虫洞). 这个就是spfa判负环的模版题,中间的cnt数组就是 ...

  3. LOJ #10084. 「一本通 3.3 练习 1」最小圈(二分+SPFA判负环)

    题意描述: 见原LOJ:https://loj.ac/problem/10084 题解: 假设所求的平均最小值为X,环上各个边的权值分别为A1,A2...Ak,可以得到: X=(A1+A2+A3+.. ...

  4. Wormholes POJ 3259(SPFA判负环)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  5. [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案

    题目链接: [APIO2017]商旅 枚举任意两个点$(s,t)$,求出在$s$买入一个物品并在$t$卖出的最大收益. 新建一条从$s$到$t$的边,边权为最大收益,长度为原图从$s$到$t$的最短路 ...

  6. Poj 3259 Wormholes(spfa判负环)

    Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 42366 Accepted: 15560 传送门 Descr ...

  7. poj 1364 King(线性差分约束+超级源点+spfa判负环)

    King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14791   Accepted: 5226 Description ...

  8. 2018.09.24 bzoj1486: [HNOI2009]最小圈(01分数规划+spfa判负环)

    传送门 答案只保留了6位小数WA了两次233. 这就是一个简单的01分数规划. 直接二分答案,根据图中有没有负环存在进行调整. 注意二分边界. 另外dfs版spfa判负环真心快很多. 代码: #inc ...

  9. BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划

    BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ...

随机推荐

  1. Web服务器的工作原理

    Web服务器的工作原理 Web服务器工作原理概述 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了 ...

  2. Linux下NFS服务器的搭建与配置

    一.NFS服务简介 NFS 就是 Network FileSystem 的缩写,最早之前是由sun 这家公司所发展出来的. 它最大的功能就是可以透过网络,让不同的机器.不同的操作系统.可以彼此分享个别 ...

  3. 我的Windows软件清单

    1.evernote : 没错,这篇笔记就是用 evernote 写的,说实话,这款产品我只是在PC上用,虽然手机上也下了,不过似乎体验不是很好(可能是屏幕不够大的原因),用得非常少.这个软件里面可以 ...

  4. 阻塞非阻塞,同步异步四种I/O方式

    举一个去书店买书的例子吧: (同步)阻塞: 你去书店买书,到柜台告诉店员,需要买一本APUE,然后一直在柜台等.(阻塞) 店员拿到书以后交给你. (同步)非阻塞: 你去书店买书,到柜台告诉店员A,需要 ...

  5. Tornado中Cookie过期问题

    首先,web应用程序是使用HTTP协议进行数据传输,因为HTTP协议是无状态的,所以一旦提交数据完成后,客户端和服务器端的连接就会被关闭,再次进行数据的交换就得重新建立新的连接,那么,有个问题就是服务 ...

  6. rem字体响应式布局

    引用js,自动算字体大小,响应式布局 <script> var iScale = 1; iScale = iScale / window.devicePixelRatio; documen ...

  7. .net mvc 扩展IPrincipal接口

    .自定义实现IPrincipal接口的类 interface ICustomPrincipal : IPrincipal { string Identifier { get; set; } strin ...

  8. Q_OBJECT

    所有QObject的派生类在官方文档中都推荐在头文件中放置宏Q_OBJECT,那么该宏到底为我们做了哪些工作?在qobjectdef.h中有下面的代码: #define Q_OBJECT \ publ ...

  9. js之数据类型

    1.数组类型 var Array=new Array(); 长度可变 var Array=new Array(n); 长度为n的数组 var Array=new Array("A" ...

  10. jquery修改table某列的值

    开发的过程中,我们经常会遇到一些数和值之间的转换,比如本例:学部:1.小学,2.初中,3.高中;当然实现方法很多种,可以后台代码,也可以使用脚本... 修改前: 修改后: 代码: $("#t ...