UVa 11090 Going in Cycle!!【Bellman_Ford】
题意:给出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的条件下能够找到负环,那么就二分查找一步步找出平均值最小的环,直到到达循环退出的精度
代码学习的标程= =
#include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#define mod=1e9+7; using namespace std; typedef long long LL;
const int INF = 0x7fffffff;
const int maxn=; struct Edge{
int from,to; double dist;
}; struct BellmanFord{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn];
double d[maxn];
int p[maxn];
int cnt[maxn]; void init(int n){
this->n=n;
for(int i=;i<n;i++) G[i].clear();
edges.clear();
} void AddEdges(int from,int to,double dist){
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-);
} bool negativeCycle(){
queue<int> Q;
memset(inq,,sizeof(inq));
memset(cnt,,sizeof(cnt));
for(int i=;i<n;i++) {d[i]=;inq[]=true;Q.push(i);} while(!Q.empty()){
int u=Q.front();Q.pop();
inq[u]=false;
for(int i=;i<G[u].size();i++){
Edge& e=edges[G[u][i]];
if(d[e.to]>d[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
if(!inq[e.to]){
Q.push(e.to);
inq[e.to]=true;
if(++cnt[e.to]>n)
return true;
}
}
}
}
return false;
}
}; BellmanFord solver; bool test(double x){
for(int i=;i<solver.m;i++)
solver.edges[i].dist-=x; bool ret=solver.negativeCycle();
for(int i=;i<solver.m;i++)
solver.edges[i].dist+=x;
return ret;
} int main(){
int T;
scanf("%d",&T);
for(int kase=;kase<=T;kase++){
int n,m;
scanf("%d %d",&n,&m);
solver.init(n);
int ub=;
while(m--){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);u--;v--;ub=max(ub,w);
solver.AddEdges(u,v,w);
}
printf("Case #%d: ",kase);
if(!test(ub+)) printf("No cycle found.\n");
else{
double L=,R=ub;
while(R-L>1e-){
double M=L+(R-L)/;
if(test(M)) R=M;else L=M;
}
printf("%.2lf\n",L);
}
}
return ;
}
UVa 11090 Going in Cycle!!【Bellman_Ford】的更多相关文章
- UVA 11090 : Going in Cycle!! 【spfa】
题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; const double INF=1e18; ; ; in ...
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
UVA 11090 - Going in Cycle!! option=com_onlinejudge&Itemid=8&page=show_problem&category= ...
- UVA - 11090 - Going in Cycle!!(二分+差分约束系统)
Problem UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...
- 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 ...
- uva 10154 - Weights and Measures【dp】qi
题意:uva 10154 - Weights and Measures 题意:有一些乌龟有一定的体重和力量,求摞起来的最大高度.力量必须承受其上面包含自己的所有的重量. 分析:先按其能举起来的力量从小 ...
- UVa 11090 Going in Cycle!! (Bellman_Ford)
题意:给定一个加权有向图,求平均权值最小的回路. 析:先十分答案,假设答案是 ans,那么有这么一个回路,w1+w2+w3+...+wk < k*ans,这样就是答案太大,然后移项可得,(w1- ...
- UVA 11090 Going in Cycle!!
要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了. 按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) & ...
- UVA 11090 Going in Cycle!! SPFA判断负环+二分
原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVA 11090 - Going in Cycle!! SPFA
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
随机推荐
- logback日志项目使用方法 - 150205交易模块添加日志信息logback,orderNo订单号为log主键便于跟踪,数字常量化,解决取消支付BUG,弱网络环境原因
1.项目里面的日志,便于跟踪数据的变更和异常错误信息产生.生产环境的日志级别是INFO,测试环境日志级别DEBUG,如果生产环境的日志级别是DEBUG,虽然方便查询问题,可以看到SQL语句等信息,但是 ...
- POJ 2823
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 35941 Accepted: 10636 ...
- php string转换为int
本身 var_dump : string(3) "002" 本身 is_numeric : bool(true) 本身 转换为数字 : int(2) 本身 转换为数字变量 : in ...
- .htaccess文件的作用(访问控制)
在线工具: http://www.htaccesseditor.com/sc.shtml 说到.htaccess文件,我想对于wordpress新手或者老手都应该不是很熟悉,也没有多少这方面的概念吧, ...
- linux系统中如何进入退出vim编辑器,方法及区别
在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了.偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致强 ...
- C# Socket 入门2(转)
现在来传一个图片看看, 改改程序, 看看服务端 图片为 140K, 1.jgp 1. 服务端 1 using System; 2 using System.Collections.Generic; ...
- 20个最受欢迎的Linux命令
http://code.csdn.net/news/2819566 1. 以 root 帐户执行上一条命令 sudo !! 2. 利用 Python 搭建一个简单的 Web 服务器,可通过 ht ...
- Java-马士兵设计模式学习笔记-总结
<马士兵设计模式学习>学习了以下模式: 1.装饰者模式(例子:水管工,木工) 2.策略模式(例子:老师用职称比大小.学生用成绩比大小) 3.简单工厂模式(例子:VechileFactory ...
- 图解TCP/IP读书笔记(二)
图解TCP/IP读书笔记(二) 第二章.TCP/IP基础知识 一.TCP/IP出现的背景及其历史 年份 事件 20世纪60年代后半叶 应DoD(美国国防部)要求,美国开始进行通信技术相关的研发 196 ...
- iOS xcode缓存问题
Question: When I try to build my app in Xcode, I get this error message:PCH file built from a differ ...