首页 > 其他分享 >Link with Game Glitch(负环)

Link with Game Glitch(负环)

时间:2022-08-19 22:45:53浏览次数:88  
标签:frac leq int double 负环 Glitch Game wc include

题意

有\(n\)个物品,\(m\)个转换,每\(ka_i\)个\(b_i\)类物品可以换\(w \cdot kc_i\)个\(d_i\)类物品。其中\(k\)为任意正实数。

求最大的\(0 \leq w \leq 1\)使得不存在一种转换方式可以得到无限多的某类物品。

题目保证当\(w = 1\)时,必然存在一种转换方式使得某类物品可以得到无限多个。

(题目翻译来源于emofunc的讲解PPT)

题目链接:https://ac.nowcoder.com/acm/contest/33187/D

数据范围

\(2 \leq n \leq 1000\)
\(2 \leq m \leq 2000\)

思路

由于\(k\)为任意正实数,因此我们可以计算每个\(b_i\)可以换多少个\(d_i\),答案是\(\frac{w \cdot c_i}{a_i}\)。

然后我们再考虑什么情况下某类物品可以得到无限多个,不妨设该类物品为\(p_0\),且初始数量为\(1\)。使用\(p_0\)换取若干\(p_1\),然后\(p_1\)再换取若干\(p_2\),依此类推,最终\(p_{k-1}\)换取若干\(p_k\),\(p_k\)再换取若干\(p_0\)。如果一轮循环之后的\(p_0\)个数大于\(1\),则最终\(p_0\)可以无限获得。

一轮循环之后的\(p_0\)个数为\(\frac{wc_1}{a_1} \cdot \frac{wc_2}{a_2} \cdots \frac{wc_k}{a_k} \cdot \frac{wc_0}{a_0}\)。为了方便计算,我们将个数取对数,可以将条件转化为:\(\sum\limits_{i=0}^k \log (\frac{wc_i}{a_i}) > 0\),即:\(\sum\limits_{i=0}^k -\log (\frac{wc_i}{a_i}) < 0\)。

因此,我们在\(b_i\)与\(d_i\)之间连一条权值为\(-\log(\frac{c_i}{a_i})\)的有向边。然后二分\(w\)。最后使用spfa算法判断图中是否存在负环即可。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

const int N = 2010;
const double eps = 1e-8;

int n, m;
int h[N], e[N], ne[N], idx;
double w[N], d[N];
bool st[N];
int cnt[N];

void add(int a, int b, double c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

bool check(double x)
{
    queue<int> que;
    for(int i = 1; i <= n; i ++) {
        que.push(i);
        st[i] = true;
        cnt[i] = 0;
        d[i] = 0;
    }
    double k = log(x);
    while(que.size()) {
        int t = que.front();
        que.pop();
        st[t] = false;
        for(int i = h[t]; ~i; i = ne[i]) {
            int j = e[i];
            if(d[j] > d[t] - w[i] - k) {
                d[j] = d[t] - w[i] - k;
                cnt[j] = cnt[t] + 1;
                if(cnt[j] >= n) return false;
                if(!st[j]) {
                    st[j] = true;
                    que.push(j);
                }
            }
        }
    }
    return true;
}

int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    for(int i = 0; i < m; i ++) {
        int a, b, c, d;
        scanf("%d%d%d%d", &a, &b, &c, &d);
        add(b, d, log(1.0 * c / a));
    }
    double l = 0.0, r = 1.0;
    for(int i = 0; i < 100; i ++) {
        double mid = (l + r) / 2;
        if(check(mid)) l = mid;
        else r = mid;
    }
    printf("%.10f\n", l);
    return 0;
}

标签:frac,leq,int,double,负环,Glitch,Game,wc,include
From: https://www.cnblogs.com/miraclepbc/p/16603542.html

相关文章

  • 2022/8/19日测试 (内含Ticket Game,生日蛋糕,最优贸易,装满的油箱,道路游戏)
    TicketGame标签:思维--------------------------------------------------------------------------------------------------------Alice和Bob生活在Berland。Berland......
  • Game Theory
    GameTheory目录博弈的基本概念组合游戏SG函数经典组合游戏模型导言:博弈的基本概念博弈论是研究具有斗争和竞争性质现象的数学理论和方法,博弈论,又称为对策论(GameTh......
  • CF1719A Chip Game 题解
    题目传送门。思路当其中一个人不能动的时候,这个人一定位于点\((n,m)\)上。令点\((n,m)\)为终点。当\(n\)和\(m\)都是奇数或当\(n\)和\(m\)都是偶数时,赢的人......
  • 搭建UnityGameFramework框架最低需求项目
    1、下载GameFramework包进入官网的下载页面下载2021.05.31版本https://gameframework.cn/download/2、新建Unity项目,然后把包导入3、新建Editor文件夹,并创建GameFr......
  • CF1498F Christmas Game
    problem一棵树,有root,一个点只能向根跳k步直到不能走,问先手必败还是必胜。root从1到n,回答n次solution一次的话就是一个阶梯nim。多次的话,就要换根。换根的话,虽然会全......
  • 多校8 D Poker Game: Decision
    problem暴力sg,打牌code#include<bits/stdc++.h>#defineFOR(i,a,b)for(inti=a;i<=b;++i)#definelllonglongusingnamespacestd;constint_=1e6+7;//const......
  • NC24870 [USACO 2009 Dec G]Video Game Troubles
    题目链接题目题目描述FarmerJohn'scowslovetheirvideogames!FJnoticedthatafterplayingthesegamesthathiscowsproducedmuchmoremilkthanusual,s......
  • 再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(6) ——《Temporal Difference Learn
    《2048》游戏在线试玩地址:https://play2048.co/  如何解决《2048》游戏源于外网的一个讨论帖子,而这个帖子则是讨论如何解决该游戏的最早开始,可谓是“缘起”:Whatis......