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。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
using namespace std;
typedef long long LL;
const int maxn = 1005,maxm = 105;
const double eps = 1e-3;
const int inf = 0x7fffffff;
int v[maxn];
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*5];
int head[maxn],vis[maxn],_v[maxn],cnt[maxn],ecnt,n,m;
double dist[maxn];
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
}
void init()
{
for(int i = 1;i <= n;++i)
RD(_v[i]);
ecnt = 0;
clr1(head);//判负环的初始化
int u,v,w;
while(m--){
RD3(u,v,w);
add(u,v,w);
}
return ;
}
bool spfa(double mid)
{
clr0(vis),clr0(cnt);
fill(dist,dist + n + 1,inf);
dist[1] = 0;
queue<int> q;
q.push(1);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
cnt[u]++;
if(cnt[u] > n)
return true;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v;
double tmp = mid*e[i].w - _v[v];//"边权"
if(dist[u] + tmp < dist[v]){
dist[v] = dist[u] + tmp;
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
return false;
}
void work()
{
double l = 0,r = 10000,mid,ans;
while(r - l > eps){
mid = (l + r)/2;
if(spfa(mid)){
ans = mid;
l = mid - 0.000001;
}else
r = mid + 0.000001;
}
printf("%.2f\n",ans);
}
int main()
{
while(~RD2(n,m)){
init();
work();
}
return 0;
}

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. 转载:shell脚本之sed使用----替换、变量、转义字符

    sed替换的基本语法为:----s后面跟的是分隔符,原字符串可使用.*这种正则表达式进行整行替换 代码如下: sed 's/原字符串/替换字符串/' 单引号里面,s表示替换,三根斜线中间是替换的样式, ...

  2. Java 的replace和replaceAll的使用

    (1)replace() 方法通过用 newChar 字符替换字符串中出现的所有 oldChar 字符,并返回替换后的新字符串. public String replace(char oldChar, ...

  3. SAP 创建物料主数据分类视图特性

    1.CL01创建物料分类 2.去CT04中去创建特性值 创建完成之后保存, 3.创建物料的分类视图,选择相应的特性值

  4. 05-Java中的String类

    程序设计思路: 首先目标是使输入的字符串加上某个数变成另一个字符串,从而相当于对字符串进行加密. 第一步输入一个字符串String类型: 第二步把这个字符串转变成字符数组: 第三步让这个数组的每一个字 ...

  5. python学习之——splinter使用

    开始学习使用splinter工具了,目前是摸索中,先熟悉splinter工具的使用方法~~ 实现功能: 打开firefox浏览器->www.baidu.com->输入关键词 python, ...

  6. JS之函数表达式

    度过一个愉快短暂的周末,又可以开始学习了!我爱学习,学习使人进步.今天学习函数表达式,着重学习下闭包函数. 函数表达式 可以在定义的函数声明之前调用它,但是不能在定义函数表达式之前调用它 /** * ...

  7. js ShowDialogModal 关闭子页面并刷新父页面,保留查询条件

    不知道大家有没有碰到类似的问题,当时的你是什么思路来处理这个问题呢?是url,session,cookie,还是…… 今天笔者就遇到了这个问题,当时的想法如:url,session,cookie都尝试 ...

  8. 小米Git

    这个题目的意思其实就是要分别从根节点开始遍历(dfs)到给定的两个点,然后从得出的路径中获取最早相同的点即为结果.   class Solution { public: /** * 返回git树上两点 ...

  9. node服务器

    markdown support HTTP服务器 一.服务器基本方法 "use strict"; // 1.加载http模块 const http = require('http' ...

  10. linux服务器apache 一个IP,一个端口,建立多个网站的方法。

    找到apache-tomcat-6.0.14\conf\server.xml ,再services 后面添加此段代码: Xml代码 <!-- 此处  新增的项目配置-->  <Ser ...