题意:给出n个点m条边的加权有向图,求平均值最小的回路

自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对

后来看书= =好巧妙的办法, 使用二分法求解,首先记录下来这m条边的最大权值ub

然后可以猜测一个mid,只需要判断是否存在平均值小于mid的回路 假设存在一个包含k条边的回路,回路上各条边的权值分别为w1,w,2,w3,----,wk

那么

w1+w2+w3+----+wk<k*mid

又因为联想到Bellman_Ford可以解决负环,把上式转化一下

(w1-mid)+(w2-mid)+(w3-mid)+----(wk-mid)<0

这样先将每条边w(a,b)转化成为w(a,b)-mid,再判断“新”的图中是否存在负环

自己看的时候有两个不明白的,就是最开始判断的时候为什么要用ub+1,

是因为ub+1是最差的答案了,它能够尽可能的使得每条边负得最多,如果在这种情况下都找不到负环,那么一定不存在负环

然后就是如果在ub+1的条件下能够找到负环,那么就二分查找一步步找出平均值最小的环,直到到达循环退出的精度

代码学习的标程= =

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include <cmath>
  5. #include<stack>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<queue>
  10. #include<algorithm>
  11. #define mod=1e9+7;
  12.  
  13. using namespace std;
  14.  
  15. typedef long long LL;
  16. const int INF = 0x7fffffff;
  17. const int maxn=;
  18.  
  19. struct Edge{
  20. int from,to;
  21.  
  22. double dist;
  23. };
  24.  
  25. struct BellmanFord{
  26. int n,m;
  27. vector<Edge> edges;
  28. vector<int> G[maxn];
  29. bool inq[maxn];
  30. double d[maxn];
  31. int p[maxn];
  32. int cnt[maxn];
  33.  
  34. void init(int n){
  35. this->n=n;
  36. for(int i=;i<n;i++) G[i].clear();
  37. edges.clear();
  38. }
  39.  
  40. void AddEdges(int from,int to,double dist){
  41. edges.push_back((Edge){from,to,dist});
  42. m=edges.size();
  43. G[from].push_back(m-);
  44. }
  45.  
  46. bool negativeCycle(){
  47. queue<int> Q;
  48. memset(inq,,sizeof(inq));
  49. memset(cnt,,sizeof(cnt));
  50. for(int i=;i<n;i++) {d[i]=;inq[]=true;Q.push(i);}
  51.  
  52. while(!Q.empty()){
  53. int u=Q.front();Q.pop();
  54. inq[u]=false;
  55. for(int i=;i<G[u].size();i++){
  56. Edge& e=edges[G[u][i]];
  57. if(d[e.to]>d[u]+e.dist){
  58. d[e.to]=d[u]+e.dist;
  59. p[e.to]=G[u][i];
  60. if(!inq[e.to]){
  61. Q.push(e.to);
  62. inq[e.to]=true;
  63. if(++cnt[e.to]>n)
  64. return true;
  65. }
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. };
  72.  
  73. BellmanFord solver;
  74.  
  75. bool test(double x){
  76. for(int i=;i<solver.m;i++)
  77. solver.edges[i].dist-=x;
  78.  
  79. bool ret=solver.negativeCycle();
  80. for(int i=;i<solver.m;i++)
  81. solver.edges[i].dist+=x;
  82. return ret;
  83. }
  84.  
  85. int main(){
  86. int T;
  87. scanf("%d",&T);
  88. for(int kase=;kase<=T;kase++){
  89. int n,m;
  90. scanf("%d %d",&n,&m);
  91. solver.init(n);
  92. int ub=;
  93. while(m--){
  94. int u,v,w;
  95. scanf("%d %d %d",&u,&v,&w);u--;v--;ub=max(ub,w);
  96. solver.AddEdges(u,v,w);
  97. }
  98. printf("Case #%d: ",kase);
  99. if(!test(ub+)) printf("No cycle found.\n");
  100. else{
  101. double L=,R=ub;
  102. while(R-L>1e-){
  103. double M=L+(R-L)/;
  104. if(test(M)) R=M;else L=M;
  105. }
  106. printf("%.2lf\n",L);
  107. }
  108. }
  109. return ;
  110. }

UVa 11090 Going in Cycle!!【Bellman_Ford】的更多相关文章

  1. UVA 11090 : Going in Cycle!! 【spfa】

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; const double INF=1e18; ; ; in ...

  2. UVA 11090 - Going in Cycle!!(Bellman-Ford)

    UVA 11090 - Going in Cycle!! option=com_onlinejudge&Itemid=8&page=show_problem&category= ...

  3. UVA - 11090 - Going in Cycle!!(二分+差分约束系统)

    Problem  UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...

  4. 141. Linked List Cycle【easy】

    141. Linked List Cycle[easy] Given a linked list, determine if it has a cycle in it. Follow up:Can y ...

  5. uva 10154 - Weights and Measures【dp】qi

    题意:uva 10154 - Weights and Measures 题意:有一些乌龟有一定的体重和力量,求摞起来的最大高度.力量必须承受其上面包含自己的所有的重量. 分析:先按其能举起来的力量从小 ...

  6. UVa 11090 Going in Cycle!! (Bellman_Ford)

    题意:给定一个加权有向图,求平均权值最小的回路. 析:先十分答案,假设答案是 ans,那么有这么一个回路,w1+w2+w3+...+wk < k*ans,这样就是答案太大,然后移项可得,(w1- ...

  7. UVA 11090 Going in Cycle!!

    要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了. 按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) & ...

  8. UVA 11090 Going in Cycle!! SPFA判断负环+二分

    原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  9. UVA 11090 - Going in Cycle!! SPFA

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

随机推荐

  1. maven 构建spring ssh mybatis 配置

    详情参与 http://blog.csdn.net/yuguiyang1990/article/details/8811817 前面我们使用Maven构建了Struts2项目,这里我们来试一下Hibe ...

  2. 如何使用 OneAPM 监控微软 Azure Cloud Service ?

    不知不觉微软 Azure 已经进入中国市场近两年的时间.那么 Azure 平台的性能究竟如何?资源加载的延迟.虚拟机的稳定性等问题是否切实满足客户期许.这些都是大家对微软 Azure 这个国外的云服务 ...

  3. Unit4中的Annotation

    Unit4中的Annotation(注解.注释) JUnit4 使用 Java 5 中的注解(annotation),以下是JUnit4 常用的几个annotation介绍@Before:初始化方法@ ...

  4. 【poj1284-Primitive Roots】欧拉函数-奇素数的原根个数

    http://poj.org/problem?id=1284 题意:给定一个奇素数p,求p的原根个数. 原根: { (xi mod p) | 1 <= i <= p-1 } is equa ...

  5. C#文件输入输出流

    从输入流中读取数据(行读取字符串) using System; using System.Collections.Generic; using System.Linq; using System.Te ...

  6. mq_unlink

    NAME mq_unlink - 销毁一个消息队列 (REALTIME) SYNOPSIS #include <mqueue.h> int mq_unlink(const char *na ...

  7. Java 包装类中的静态函数

    所有的核心类型转化 全是基于这个图的 是不是很简单 so easy~~~ 不过下面的这些函数也是很重要的哦~~~ 以后就可以随意发挥了 猜API吧!

  8. Spring中 @Autowired注解与@Resource注解的区别

    Spring中 @Autowired注解与@Resource注解的区别在Spring 3.X中经常使用到@Autowired和@Resource进行装配.这两个注解的差异在何处???相同点:@Reso ...

  9. eclipse使用replace命令替换整个project/workspace的某个字符串

    比如说为了在调试的时候方便,我的应用程序中有很多System.out.println() 调试好了,要发布了,如何把这些一次性注释掉呢?见下图

  10. HDU 4634 Swipe Bo 状态压缩+BFS最短路

    将起始点.终点和钥匙统一编号,预处理: 1.起始点到所有钥匙+终点的最短路 2.所有钥匙之间两两的最短路 3.所有钥匙到终点的最短路 将起始点和所有钥匙四方向出发设为起点BFS一遍,求出它到任意点任意 ...