算法竞赛进阶指南 0x65 负环与差分约数

这里与最短路密切相关

可以使用spfa,利用spfa的原理(cnt数组),如果发现一个点是通过了超过n-1条边更新而来,那么就说明存在负环

给定一张 L 个点、 P 条边的有向图,每个点都有一个权值 f[i],每条边都有一个权值 t[i]。

求图中的一个环,使”环上各点的权值之和”除以”环上各边的权值之和”最大。

输出这个最大值。 注意 :数据保证至少存在一个环。

输入格式

第一行包含两个整数 LP

接下来 L 行每行一个整数,表示 f[i]。

再接下来 P 行,每行三个整数 abt[i],表示点 ab 之间存在一条边,边的权值为 t[i]。

输出格式

输出一个数表示结果,保留两位小数。

数据范围

2L1000,

2P5000,

1f[i] ,t [i ]1000

输入样例:

5 7
30
10
10
5
10
1 2 3
2 3 2
3 4 5
3 5 2
4 5 5
5 1 3
5 2 2

输出样例:

6.00

注意:由于是分数的最优化问题,所以我想到了0/1规划。

算法竞赛进阶指南 0x65 负环与差分约数
#include
using namespace std;
#define N 1005
#define M 5005
int head[N], tot, ver[M], nxt[M], from[M], edge[M];
int head2[N], tot2, ver2[M], nxt2[M];
double edge2[M];
int n, m;
int a[N];//存放点的权值
const double eps = 1e-5;
int cnt[N];//通过这一个数组配合spfa进行求有没有负环
bool v[N];
queueq;
double d[N];//注意取值

inline void add(int x, int y, int z)
{
    ver[++tot] = y;
    edge[tot] = z;
    from[tot] = x;
    nxt[tot] = head[x];
    head[x] = tot;
}
inline void add2(int x, int y, double z)
{
    ver2[++tot2] = y;
    edge2[tot2] = z;
    nxt2[tot2] = head2[x];;
    head2[x] = tot2;
}
bool judge(double mid)
{
    for(int i = 1; i  d[x] + z)
            {
                d[y] = d[x] + z;
                cnt[y] = cnt[x] + 1;
                if(cnt[y] >= n) return true;
                if(!v[y])
                {
                    v[y] = true;
                    q.push(y);
                }
            }
        }
    }
    return false;
}
int main()
{
    //tot = 1;
    scanf("%d%d", &n, &m);
    for(int i = 1; i  eps)
    {
        double mid = (l + r) / 2;
        if(judge(mid)) l = mid;
        else r = mid;
    }
    printf("%.2lf", l);
    return 0;
}

差分约束系统

由于差分的形式与图论中长得比较像,所以进行等价为最短路(bellman-ford中的三角不等式)

算法竞赛进阶指南 0x65 负环与差分约数

给定 n 个区间 [a i, bi ]n 个整数 ci。

你需要构造一个整数集合 Z,使得 i [1, n], Z 中满足 ai x b i 的整数 x 不少于 ci 个。

求这样的整数集合 Z 最少包含多少个数。

输入格式

第一行包含整数 n

接下来 n 行,每行包含三个整数 ai ,b i, ci。

输出格式

输出一个整数表示结果。

数据范围

1n50000,

0ai ,b i50000,

1ci b iai +1

输入样例:

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

输出样例:

6

算法竞赛进阶指南 0x65 负环与差分约数
#include
using namespace std;
#define N 50005
int s[N];
int head[N], tot, ver[3*N], nxt[3*N], edge[3*N];
int d[N];
bool v[N];
queueq;
inline int num(int x)
{
    return x == -1?50001:x;
}

inline void add(int x, int y, int z)
{
    ver[++tot] = y;
    edge[tot] = z;
    nxt[tot] = head[num(x)];
    head[num(x)] = tot;
}

void spfa()
{
    memset(d, 0xcf, sizeof(d));//尽量往小,让约束之后的值尽可能小
    d[num(-1)] = 0;
    v[num(-1)] = true;
    q.push(-1);
    while(q.size())
    {
        int x = q.front();
        q.pop();
        v[num(x)] = false;
        for(int i = head[num(x)]; i; i = nxt[i])
        {
            int y = ver[i], z = edge[i];
            if(d[num(y)] < d[num(x)]+z)
            {
                d[num(y)] = d[num(x)]+z;
                if(!v[num(y)])
                {
                    v[num(y)] = true;
                    q.push(y);
                }
            }
        }
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i

Original: https://www.cnblogs.com/xjsc01/p/16606973.html
Author: 心坚石穿
Title: 算法竞赛进阶指南 0x65 负环与差分约数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/605215/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 随机算法入门:洗牌算法

    洗牌算法是什么? 其实就理解为生成一个随机数列的一个简单操作而已。 怎么生成? 我们先讲下一般我们会想到的一个解法——标记。 假设我们的数组为a,ai 代表数组a第i个数。 一个布…

    数据结构和算法 2023年6月7日
    090
  • 二叉树的遍历 → 不用递归,还能遍历吗

    开心一刻 某同学牙龈发炎去看医生,医生说要动手术 同学说:以前没做过手术,有点紧张 医生说:不用紧张,我也是第一次做手术 听到医生这么说,同学更紧张了 这时候护士走过来,问医生:麻…

    数据结构和算法 2023年6月7日
    094
  • 四大经典算法思想

    最经典的算法思想有以下几种: 贪心算法:每一步都采用最优的选择,从而希望结果是最好的 分治算法:将原问题拆分成多个结果类似的子问题,递归解决后再合并其结果 回溯算法:类似于试探性枚…

    数据结构和算法 2023年6月8日
    093
  • 「」高维前缀和以及其他

    给一个 intrada 性质的问题: 求 (\displaystyle F[mask] = \sum_{i \subseteq mask} A[i]) 这个形式看起来会很像一个 a…

    数据结构和算法 2023年6月12日
    094
  • 归并排序

    跳转地址 归并排序的重点是合并,利用双指针算法,排序的是否稳定是指如果两个数的大小相同,在经过排序后相对位置不变,那么这个排序就是稳定的,否则就是不稳定的 归并排序的思路是将数组按…

    数据结构和算法 2023年6月8日
    0111
  • 清除 GitHub 历史记录的隐私信息

    有的时候我们在提交到github上的内容不小心含有敏感代码,比如密码,公司的服务器IP等。这个时候就要通过一些手段清除这些信息。 下面通过例子演示如何清理敏感信息 仓库名:Spac…

    数据结构和算法 2023年6月7日
    0134
  • Vector源码解读

    阅读源码是提高编程技能的有效方式… 面试中也经常问到源码相关的问题….. 在解读Vector时大家可以先解读ArrayList,因为这个两个的逻辑几乎是一样…

    数据结构和算法 2023年6月12日
    081
  • vscode+emmylua搭建lua开发环境

    下载vscode Download Visual Studio Code – Mac, Linux, Windows User Installer:安装后只有当前用户可…

    数据结构和算法 2023年6月7日
    0100
  • CF 793 div2 E 题解

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    数据结构和算法 2023年6月12日
    0121
  • 2022省集前集训

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/winterfrost/p/2022pyyz-jixun…

    数据结构和算法 2023年6月12日
    087
  • 初识设计模式-适配器模式

    适配器在生活中经常见到,如手机、笔记本电脑的电源适配器,USB 转接头都是常见的适配器。 在设计模式当中,适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。 在类适配器模…

    数据结构和算法 2023年6月8日
    097
  • 【POJ 3268 】Silver Cow Party (最短路 Dijkstra算法)

    Descriptions 给出n个点和m条边,接着是m条边,代表从牛a到牛b需要花费c时间,现在所有牛要到牛x那里去参加聚会,并且所有牛参加聚会后还要回来,给你牛x,除了牛x之外的…

    数据结构和算法 2023年6月14日
    087
  • 【POJ 2533】Longest Ordered Subsequence (最长上升子序列 简单dp)

    Longest Ordered Subsequence 搬中文 Descriptions: 给出一个序列,求出这个序列的最长上升子序列。 序列A的上升子序列B定义如下: Input…

    数据结构和算法 2023年6月14日
    087
  • 做题记录2022.4.29洛谷P1631序列合并

    可以很容易地想出暴力思路,但复杂度高达O(n2),所以必须优化 思路1:不难发现在a数组到i,b数组到j处,在它们前面的有ij个,这ij个数不可能比它大,所以只要在暴力枚举过程中判…

    数据结构和算法 2023年6月12日
    070
  • [LC814]二叉树剪枝

    题目 题目地址 分析 这道题符合递归的性质,对于当前的节点node,当且仅当其左右孩子都为不包含1的子树,且node.val=1时,node所在的子树才符合”不包含1的…

    数据结构和算法 2023年6月8日
    070
  • 蓝桥杯 ALGO-985 幸运的店家(贪心)

    试题 算法训练 幸运的店家 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 炫炫开了一家商店,卖的货只有一个,XXX,XXX卖N元钱。有趣的是,世界上只有面值为3…

    数据结构和算法 2023年6月7日
    098
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球