Luogu 3778 [APIO 2017] 商旅

2023-05-16

          • 传送门
          • 思路
          • 参考代码

传送门
思路

  唉,我太弱了,什么都不会。看到这道题就想到了二分答案找负环,但是怎么做呢?完全不会。唉,我太弱啦!

  先注意题目中说可以重复经过点和边,这启示我们:如果使用一般的算法,很难做到处理可以重复走的情况。另外,当务之急是要处理出走一个环的最大收益,但是我们不知道到底该怎么在环上走,问题一下就变得复杂了起来。

  观察发现,一个环路一定是这样走的:在一个起点买一件物品,走到一个地方把它卖掉,再买一个物品,再走到一个地方把它卖掉……但是有可能有部分地方我们没有买物品啊,很简单,只需要增加一种买入和卖出价都为 0 0 的“空物品”就好了。

  现在,如果我们知道了买入点和卖出点,就相当于知道了最大收益 s(应该注意到,这个收益不应小于 0 0 )。另外,如果我们知道了两个点,那它们之间的最短路径 l 是确定的。至此,问题终于变成了经典的求环的最大平均边权问题了。只需要二分答案,然后将式子 sl=ans ∑ s ∑ l = a n s 变成 sl×ans=0 ∑ s − ∑ l × a n s = 0 ,再判断负圈就好了。

  具体地说,如果有 sl×ans0 ∑ s − ∑ l × a n s ≥ 0 ,就相当于是说存在一个环使得 slans ∑ s ∑ l ≥ a n s ,即 ans a n s 可以更大。所以我们的任务是判断是否存在正圈。方法是把所有边权取负,然后求负圈就可以了。(想一想,为什么不能把不等号反号并改变二分方向然后直接求负圈,而必须求是否存在正圈)

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef LL INT_PUT;
INT_PUT readIn()
{
    INT_PUT a = 0; bool positive = true;
    char ch = getchar();
    while (!(ch == '-' || std::isdigit(ch))) ch = getchar();
    if (ch == '-') { positive = false; ch = getchar(); }
    while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }
    return positive ? -a : a;
}
void printOut(INT_PUT x)
{
    char buffer[20]; int length = 0;
    if (x < 0) putchar('-'); else x = -x;
    do buffer[length++] = -(x % 10) + '0'; while (x /= 10);
    do putchar(buffer[--length]); while (length);
}

LL INF;
const int maxn = 105;
const int maxk = 1005;
int n, m, k;
int b[maxn][maxk];
int s[maxn][maxk];

struct Graph
{
    struct Edge
    {
        int to;
        double cost;
        int next;
    } edges[maxn * maxn];
    int i;
    int head[maxn];
    Graph() : i() { memset(head, -1, sizeof(head)); }
    void addEdge(int from, int to, double cost)
    {
        edges[i].to = to;
        edges[i].cost = cost;
        edges[i].next = head[from];
        head[from] = i;
        i++;
    }
    void clear()
    {
        i = 0;
        memset(head, -1, sizeof(head));
    }
#define idx(G) idx_##G
#define wander(G, node) for (int idx(G) = G.head[node]; ~idx(G); idx(G) = G.edges[idx(G)].next)
#define DEF(G) const Graph::Edge& e = G.edges[idx(G)]; int to = e.to; double cost = e.cost
} G;

LL earn[maxn][maxn];
double path[maxn][maxn];

struct Queue
{
    int c[maxn];
    int head, tail;
    void clear() { head = tail = 0; }
    Queue() { clear(); }
    void push(int x) { c[tail] = x; tail = tail + 1 >= maxn ? 0 : tail + 1; }
    void pop() { head = head + 1 >= maxn ? 0 : head + 1; }
    int front() { return c[head]; }
    bool empty() { return head == tail; }
} q;
bool inQ[maxn];
int enter[maxn];
bool SPFA(const Graph& G, int s, double dis[maxn])
{
    memset(inQ, false, sizeof(inQ));
    memset(enter, 0, sizeof(enter));
    std::fill(dis, dis + 1 + n, 1e20);
    q.clear();
    q.push(s);
    inQ[s] = true;
    dis[s] = 0;
    enter[s] = 1;
    while (!q.empty())
    {
        int from = q.front();
        q.pop();
        inQ[from] = false;
        wander(G, from)
        {
            DEF(G);
            if (dis[from] + cost < dis[to])
            {
                dis[to] = dis[from] + cost;
                if (++enter[to] >= n) return true;
                if (!inQ[to])
                {
                    q.push(to);
                    inQ[to] = true;
                }
            }
        }
    }
    return false;
}

Graph T;
double dis[maxn];
bool check(double s)
{
    T.clear();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (i != j)
                T.addEdge(i, j, -(earn[i][j] - path[i][j] * s));

    return SPFA(T, 1, dis);
}

void run()
{
    memset(&INF, 0x3f, sizeof(INF));

    n = readIn();
    m = readIn();
    k = readIn();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++)
        {
            b[i][j] = readIn();
            s[i][j] = readIn();
        }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            LL& t = earn[i][j];
            t = 0;
            for (int l = 1; l <= k; l++)
                if (b[i][l] != -1 && s[j][l] != -1)
                    t = std::max(t, (LL)s[j][l] - b[i][l]);
        }
    }

    for (int i = 1; i <= m; i++)
    {
        int from = readIn();
        int to = readIn();
        int cost = readIn();
        G.addEdge(from, to, cost);
    }

    for (int i = 1; i <= n; i++)
        SPFA(G, i, path[i]);

    double l = 0, r = 1e11;
    while (r - l >= 1e-2)
    {
        double mid = (l + r) / 2;
        if (check(mid))
            l = mid;
        else
            r = mid;
    }
    printOut(r);
}

int main()
{
    run();
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Luogu 3778 [APIO 2017] 商旅 的相关文章

  • Visual Studio 2017 + VisualGDB 调试Linux C++程序

    Visual Stuido版本 xff1a VisualGDB版本 xff1a 经过测试 xff0c VisualGBD 5 1暂不支持VS 2017 xff0c 5 3及以上版本在VisualGDB Project Properties
  • 过去的 2017 年

    过去的 2017 年分为两个部分 xff0c 前半部分偏忙碌 xff0c 个人时间较少 xff0c 但是收获甚微 xff1b 后半部分进入了一个学习的环境 xff0c 最主要的就是个人可自由支配的时间多了 xff0c 留给了我很多思考的时间
  • B - Palindrome-phobia(CODE FESTIVAL 2017 Final)

    题目链接 https cf17 final open contest atcoder jp tasks cf17 final b 解题思路 通过找规律发现出现的次数最多的字符与其他两个字符数量的差不能大于1 AC代码 include lt
  • 【The 2017 BAPC】C题-Collatz Conjecture ---- GCD+优化去重

    题意 给你一个大小为n的序列 xff0c 让你求里面所有子串的GCD xff0c 求里面最多有多少不同的GCD 思路 xff1a 利用集合set tmp维护 到当前子串的最后一个元素的所有GCD xff0c set ans保存所有不同种类的
  • virtual stdio 2017 问题

    严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8020 无法找到 Visual Studio 2010 的生成工具 平台工具集 61 v100 若要使用 v100 生成工具进行生成 xff0c 请安装 Visual Stud
  • 题解:luogu P5568 [SDOI2008]校门外的区间

    题解 xff1a luogu P5568 SDOI2008 校门外的区间 luogu P5568 SDOI2008 校门外的区间 前置知识 xff1a 珂朵莉树 问题一 xff1a 开闭区间 区间端点均为整数 xff0c 不妨认为 xff0
  • 【Luogu P1661】扩散

    题目 xff1a 一个点每过一个单位时间就会向四个方向扩散一个距离 xff0c 如图 两个点 a b 连通 xff0c 记作 e a b 当且仅当 a b 的扩散区域有公共部分 连通块的定义是块内的任意两个点 u v 都必定存在路径 e u
  • luogu p2651 添加括号Ⅲ

    题目描述 现在给出一个表达式 xff0c 形如a1 a2 a3 an 如果直接计算 xff0c 就是一个个除过去 xff0c 比如1 2 1 4 61 1 8 然而小A看到一个分数感觉很不舒服 xff0c 希望通过添加一些括号使其变成一个整
  • Luogu 3631 [APIO 2011] 方格染色

    传送门思路参考代码细节 传送门 思路 很不错的一道题 xff0c 用到的东西不深 xff0c 但是要想到确实需要一定思维 一开始我想的是动态规划 xff0c 发现如果要设状态需要知道一个格子左边 xff0c 上边和左上边三个格子的状态 然后
  • UOJ 2016 [APIO 2016] Gap

    传送门思路参考代码交互题 交互题大致形式Windows 平台下 xff08 Dev C 43 43 xff09 Ubuntu 平台下 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题也做不来 这道题简直就是利用
  • Luogu 1117 [NOI 2016] 优秀的拆分

    传送门思路利用后缀数组解决重复子串问题注意事项参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 连暴力都想不到 xff0c 唉 xff0c 我太弱啦 xff01 考虑暴力法 xff0c 可以枚举一个中间点
  • Luogu 2114 [NOI 2014] 起床困难综合症

    传送门思路参考代码 传送门 思路 按位贪心 但是我太弱了 xff0c 明明可以 O n O n 预处理 xff0c 我却只会 O 32 n O
  • 2017-06-08 每日一记 sqlite3_bind_blob函数

    sqlite3函数 xff1a sqlite3 bind blob stat 1 pdata int length of data in bytes NULL 参数1 xff1a sqlte stmt 参数2 xff1a 的索引 xff0c
  • 2017论文阅读:Learning a Rotation Invariant Detector with Rotatable Bounding Box

    文章代码已开源 文章目录 文章贡献1 Rotatable bounding box2 Rotation invariant detection2 1 模型结构总览2 2 模型训练2 3 实现的细节 3 实验 amp 结果 文章贡献 提出了一
  • 记录 docker 安装mssql 2017

    系统环境 xff1a 阿里云 CentOS 7 4G内存 参考 xff1a https docs microsoft com zh cn sql linux quickstart install connect docker view 61
  • 2017.04.21 麦克纳姆轮简介

    这个是德国库卡KMP omniMove移动负载平台上使用的轮子 xff0c 这个轮子的名字叫麦克纳姆轮 麦克纳姆轮是基于一个有许多位于机轮周边的轮轴的中心轮的原理上 xff0c 这些成角度的周边轮轴把一部分的机轮转向力转化到一个机轮法向力上
  • Visual Studio 2017 代码自动对齐

    点 编辑 高级 设置选定内容的格式 或者按Ctrl 43 K 然后再按Ctrl 43 F 就好了 你可以在常用快捷键自定义 窗口中进行查看 1 进入工具 选项 对话框 2 选择 环境 键盘 3 在 显示命令包含 下面的对话框中输入 对齐 关
  • 2017年408专业算法题

    文章目录 0 结果1 题目2 思路附录 0 结果 1 题目 2 思路 因为要转换为中序表达式 xff0c 因此使用中序遍历 在中序遍历的过程中 xff0c 对于当前访问的非空结点p xff0c 则先输出 34 xff0c 然后递归调用左子树
  • P1586 四方定理

    Powered by NEFU AB IN Link 文章目录 P1586 四方定理 题意 思路 代码 P1586 四方定理 题意 四方定理是众所周知的 任意一个正整数n 可以分解为不超过四个整数的平方和 给定的正整数n 编程统计它能分解的
  • 2017年全国数学建模国赛B题题目、解题思路、matlab代码(三)

    题目 移动互联网的迅速发展使得任务完成新模式 众包 的实现成为可能 这种自助式服务模式以移动互联网为劳务众包平台 通过线上 APP 建立起需要商业检查和信息搜集的企业与可以完成规定任务的大众之间的联系 从而大大节省企业调查成本 有效地保证调

随机推荐

  • 原博文地址

    由于账号问题 xff0c 现更改为这个账号 xff0c 以下为原博文地址 使用WH MOUSE LL钩子来判断按键是否是mouse event模拟的 http blog csdn net qq 26140973 article detail
  • [NOI 2003] 文本编辑器 Splay 维护序列 / 块状链表

    传送门 xff08 JZOJ xff09 xff08 第一道全国决赛题 xff09 解法 1 xff1a 使用 Splay 维护 不管怎么说 xff0c 总和刚刚学过的迎合上了 这道题可以直接上 Splay 维护线性序列 xff0c 光标位
  • 一次macOS的升级填坑(macOS Catalina - macOS Monterey)

    目录 小序一 升级前操作二 升级中三 问题填坑1 像我一样长时间卡在一个进度条怎么办2 在更新途中重启过电脑 xff08 完整流程填坑 xff09 3 安装之后不能开机 xff0c 如何紧急拷贝资料4 安装不成功 xff0c 如何重新安装系
  • CF 713C Sonya and Problem Wihtout a Legend

    文章目录 传送门题目大意正解通过维护关键点来维护信息参考代码 传送门 题目大意 给定一个长度为 n n 3000
  • Luogu 3642 [APIO 2016] 烟火表演

    传送门引例 xff08 上一道题 xff09 凸函数一开始的思路正解参考代码总结 传送门 引例 xff08 上一道题 xff09 凸函数 回忆我们上一道题是怎么做的 我们维护的东西的实质是一个 xff08 下 xff09 凸函数 由于我们的
  • Luogu 3631 [APIO 2011] 方格染色

    传送门思路参考代码细节 传送门 思路 很不错的一道题 xff0c 用到的东西不深 xff0c 但是要想到确实需要一定思维 一开始我想的是动态规划 xff0c 发现如果要设状态需要知道一个格子左边 xff0c 上边和左上边三个格子的状态 然后
  • Luogu 3632 [APIO 2011] 寻路

    传送门正解参考代码 传送门 正解 暴力连边跑最短路就好了 xff0c 只不过代码太长太难写啦 xff01 参考代码 span class hljs preprocessor include lt cstdio gt span span cl
  • Luogu 3634 [APIO 2012] 守卫

    传送门思路正解参考代码 传送门 思路 感觉自己越来越笨了 首先 xff0c 很明显这道题需要把没有看到忍者的区间给删去 xff0c 可以用前缀和 O n O n 处理 xff0c 然后对没有删去的地方重新标号 重新标号时 xff0c 需要对
  • Luogu 1552 [APIO 2012] 派遣

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题读错了两次 xff0c 一开始读成了一个一般的背包 xff0c 然后读成了一个价值和花费相同的背包 xff0c 最后才发现原来是一个价值为 1
  • 贪玩 CF 之旅

    文章目录 CF 7D Palindrome Degree http codeforces com problemset problem 7 D 题解 CF 713C Sonya and Problem Wihtout a Legend ht
  • Luogu 3638 [APIO 2013] 机器人

    传送门思路正解参考代码关于 SPFA 传送门 思路 n n 这么小 会不会是搜索题 稍有经验的我直接否定了这个结论 仔细读题并分析样例 发现原来一个位置可以有多个机器人 且机器人行走的时候无视其它机器人 那这个就是一张图啊 可以将这张图预处
  • Luogu 3647 [APIO 2014] 连珠线

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 又看错题了 题目中说一个新的珠子和一个已经添加的珠子连接起来 xff0c 我没有看到 xff0c 然后就凉了 立个 flag xff1a 已经连续看错五题了 xff0c
  • 【转】mingw64的安装方法

    转自 xff1a http write blog csdn net postlist mingw64的安装方法 1 下载ming w64 http sourceforge net projects mingw w64 files or x8
  • Luogu 3645 [APIO 2015] 雅加达的摩天楼

    传送门思路正解参考代码Update 传送门 思路 唉 xff0c 我太弱了 xff0c 我都看出来要分块了 xff0c 就是做不来 不过终于把题读对了 先来看子任务三怎么做 显然可以有一个 O m 2 O m 2
  • Luogu 3644 [APIO 2015] 八邻旁之桥

    传送门思路当 k 61 2 时参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题也做不来 很明显这道题先要把不过河的人排除了 xff0c 剩下的都是要过河的 当 k 61 1 k 61 1 时 xff0
  • Luogu 3646 [APIO 2015] 巴厘岛的雕塑

    传送门总结 APIO 2015思路参考代码总结 传送门 总结 APIO 2015 争取今天做完一套 QAQ T1 我最多之能想到从高位向低位做 xff0c 然后就完全不会了 xff1b T2 我想到了分情况讨论 xff0c 但是没有建图成功
  • UOJ 2016 [APIO 2016] Gap

    传送门思路参考代码交互题 交互题大致形式Windows 平台下 xff08 Dev C 43 43 xff09 Ubuntu 平台下 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题也做不来 这道题简直就是利用
  • CF 940F Machine Learning

    传送门题目大意思路参考代码Remarks 传送门 题目大意 给你一个数组 a 1 n n 10 5 a 1 n
  • CF 976D Degree Set

    传送门题目大意思路参考代码总结 传送门 题目大意 给你一个长度为 n n 的正整数序列 d 1 d 2 d n d1 d2 dn xff08 d 1 lt d 2 lt lt d n
  • Luogu 3778 [APIO 2017] 商旅

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 看到这道题就想到了二分答案找负环 xff0c 但是怎么做呢 xff1f 完全不会 唉 xff0c 我太弱啦 xff01 先注意题目中说可以重复经过点和边 x