【bzoj4898】商旅
Solution
 这题的话。。首先答案的形式应该是\(01\)分数规划了
 然后比较关键的一步在于,我们需要简化一下交易的过程
 具体一点就是,我们将中间经过的不交易的点和路径全部”合并“起来,只考虑买入物品和卖出物品的两个点
 首先看一下这两个点之间的路程应该怎么走
 因为路程长度是做分母的那个,所以我们肯定希望在到达同一个点的情况下走最短路,那所以这两个点一旦确定下来了,路程也就确定下来了
 两两之间最短路的求解因为\(N\)比较小所以可以直接用floyd解决
 然后接下来就是交易的物品我们要选择哪一个
 很明显是选盈利最大的那个,大力贪心就好了ovo
 所以总的来说,如果确定了进行买卖的两个点,我们走的路程一定是最短路,买卖的一定是这两个点能够交易的所有物品中,盈利最大的那个
 记两点间最短路为\(w_{i,j}\),最优的盈利为\(val_{i,j}\),那么套用分数规划的套路(Portal -->【learning】),我们需要快速求出一个环的:
\]
 与\(0\)的大小关系
 那么这个其实就直接用spfa判断是否有正环就好了
 自己跳进去的坑:
  额。。注意到这里题目说的是**利润/路径长度(向下取整) **的最大值。。
  所以!在二分答案的时候!\(l\)和\(r\)和\(mid\)用int就好了!! QWQ
  以及\(K\)的范围是\(1000\)而不是\(100\)。。。
 代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=110,M=9910,inf=2147483647;
const double eps=1e-8;
struct xxx{
    int y,x,nxt;
    double w;
}a[N*N*2];
struct Data{
    int y,x;
    int w;
}rec[N*N*2];
queue<int> q;
int h[N],cnt[N],buy[N][1010],sell[N][1010],w[N][N];
double val[N];
bool vis[N];
int n,m,K,tot,rec_cnt;
void add(int x,int y,double val);
bool spfa();
void build(double mid);
bool check(double mid);
void prework();
void floyd();
void solve();
int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    scanf("%d%d%d",&n,&m,&K);
    for (int i=1;i<=n;++i)
        for (int j=1;j<=K;++j)
            scanf("%d%d",&buy[i][j],&sell[i][j]);
    int x,y,w1;
    rec_cnt=0;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            w[i][j]=inf;
    for (int i=1;i<=m;++i){
        scanf("%d%d%d",&x,&y,&w1);
        rec[++rec_cnt].x=x; rec[rec_cnt].y=y; rec[rec_cnt].w=0;
        w[x][y]=min(w[x][y],w1);
    }
    prework();
    solve();
}
void add(int x,int y,double val){
    //printf("%d %d %.3lf\n",x,y,val);
    a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot; a[tot].w=val;
}
bool spfa(){
    while (!q.empty()) q.pop();
    int u,v;
    for (int i=1;i<=n;++i) vis[i]=true,q.push(i),cnt[i]=0,val[i]=0;
    while (!q.empty()){
        v=q.front(); q.pop();
        for (int i=h[v];i!=-1;i=a[i].nxt){
            u=a[i].y;
            if (val[u]<=val[v]+a[i].w){
                val[u]=val[v]+a[i].w;
                if (!vis[u]){
                    q.push(u),vis[u]=true,++cnt[u];
                    if (cnt[u]>n) return true;
                }
            }
        }
        vis[v]=false;
    }
    return false;
}
bool check(double mid){
    build(mid);
    return spfa();
}
void build(double mid){
    tot=0;
    for (int i=1;i<=n;++i) h[i]=-1;
    for (int i=1;i<=rec_cnt;++i)
        add(rec[i].x,rec[i].y,1.0*rec[i].w-mid*w[rec[i].x][rec[i].y]);
}
void floyd(){
    for (int k=1;k<=n;++k)
        for (int i=1;i<=n;++i){
            if (w[i][k]==inf) continue;
            for (int j=1;j<=n;++j)
                if (w[k][j]!=inf)
                    w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
        }
}
void prework(){
    floyd();
    int mx,tmp;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j){
            if (w[i][j]==inf) continue;
            mx=0;
            for (int k=1;k<=K;++k)
                if (buy[i][k]!=-1&&sell[j][k]!=-1){
                    if (sell[j][k]-buy[i][k]>mx) tmp=k;
                    mx=max(mx,sell[j][k]-buy[i][k]);
                }
            if (mx)
                rec[++rec_cnt].x=i,rec[rec_cnt].y=j,rec[rec_cnt].w=mx;
        }
}
void solve(){
    int l=0,r=1e9,mid,ans;
    while (l<=r){
        mid=(l+r)>>1;
        if (check(mid)) ans=mid,l=mid+1;
        else r=mid-1;
    }
    printf("%d\n",ans);
}
【bzoj4898】商旅的更多相关文章
- luogu3778/bzoj4898 商旅 (floyd+分数规划+spfa)
		首先floyd求出来每两点间的最短距离,然后再求出来从某点买再到某点卖的最大收益 问题就变成了找到一个和的比值最大的环 所以做分数规划,二分出来那个答案r,把边权变成w[i]-r*l[i],再做spf ... 
- 【learning】01分数规划
		问题描述 首先分数规划是一类决策性问题 一般形式是: \[ \lambda=\frac{f(x)}{g(x)} \] 其中\(f(x)\)和\(g(x)\)都是连续的实值函数,然后要求\(\lambd ... 
- [BZOJ4898] [Apio2017]商旅
		[BZOJ4898] [Apio2017]商旅 传送门 试题分析 考虑两个点之间的路径,显然如果交易的话肯定选\(S_{t,i}-B_{s,i}\)最大的. 那么我们可以先用\(Cost\)把两个点的 ... 
- 【BZOJ4898】[Apio2017]商旅 分数规划+SPFA
		[BZOJ4898][Apio2017]商旅 Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个 ... 
- BZOJ4898/5367 Apio2017商旅(分数规划+floyd)
		如果要在某点买入某物品并在另一点卖出,肯定是走其间最短路径.于是预处理任意两点间的收益和最短路径,连完边二分答案判负环即可,可以全程floyd.注意inf大小. #include<iostrea ... 
- BZOJ4898 & BZOJ5367 & 洛谷3778:[APIO2017]商旅——题解
		https://www.lydsy.com/JudgeOnline/problem.php?id=4898 https://www.lydsy.com/JudgeOnline/problem.php? ... 
- 【bzoj4898】[Apio2017]商旅  Floyd+分数规划+Spfa
		题目描述 有n个点.m条边.和k种商品.第$i$个点可以以$B_{ij}$的价格买入商品$j$,并以$S_{ij}$的价格卖出.任何时候只能持有一个商品.求一个环,使得初始不携带商品时以某种交易方式走 ... 
- bzoj4898 & loj2308 [Apio2017]商旅  最短路+01分数规划
		题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4898 https://loj.ac/problem/2308 题解 发现我们可以把整个环路分成 ... 
- 「APIO2017」商旅
		「APIO2017」商旅 题目描述 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个商人.科巴有 \(N\) 个集市, ... 
随机推荐
- 使用PHP写ajax接口
			使用PHP写ajax接口 之前有学过php都是前后端没有分离的,所以也想去了解后端是怎么写出ajax接口的,可能问了别人或者上网找了很多资料都很有有点懵,或者说直接用TP或者lavarel这些后端框架 ... 
- win2003系统网络安装——基于linux+pxe+dhcp+tftp+samba+ris
			原文发表于:2010-09-16 转载至cu于:2012-07-21 一.原理简介 PXE(preboot execute environment)工作于Client/Server的网络模式,支持工作 ... 
- kubeadm构建k8s之Prometheus-operated监控(0.18.1)
			介绍: 大家好,k8s的搭建有许多方式,也有许多快速部署的,为了简化部署的复杂度,官方也提供了开源的kubeadm快速部署,最新1.10.x版本已经可以实现部署集群, 如果你对k8s的原理已经非常了解 ... 
- leetcode27_C++Remove Element
			给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ... 
- Blockchain For Dummies(IBM Limited Edition
			Blockchain For Dummies(IBM Limited Edition)笔记 该系列内容主要介绍用于商业的区块链,有人说区块链之于贸易,犹如因特网之于信息.在商业领域区块链可以用于交易任 ... 
- IT视频课程集
			马哥Linux培训视频课程:http://pan.baidu.com/s/1pJwk7dp Oracle.大数据系列课程:http://pan.baidu.com/s/1bnng3yZ 天善智能BI培 ... 
- 与面试官谈笑风生 | Python面向对象之访问控制
			Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装.所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念 ... 
- 20172311-ASL测试 2018-1938872补充博客
			20172311-ASL测试 2018-1938872补充博客 课程:<程序设计与数据结构> 班级: 1723 姓名: 赵晓海 学号: 20172311 实验教师:王志强老师 测试日期:2 ... 
- OGNL动态实现result
			OGNL就是struts.xml文件中的<result>通过get()方法,动态获取action类中的变量 <struts> <package name="de ... 
- Optimized Flow Migration for NFV Elasticity Control
			NFV弹性控制中的流迁移优化 ABSTRACT 基于动态创建和移除网络功能实例,NFV在网络功能控制上有很大的弹性.比如,网络功能和并,网络功能拆分,负载均衡等等. 那么为了实现弹性控制,就需要网络流 ... 
