zoukankan      html  css  js  c++  java
  • P1113 杂务

    显然地,本题中各项工作是有一定的依赖条件的,也就是说我们在进行工作 X 之前可能需要先进行一些其他的工作。

    而完成工作 X 所需的时间和所有 X 所依赖的工作完成的时间的最大值有关。(应该还好理解吧)

    在这道题中,我们可以列出一个简单的 DP 转移方程:

    $$f_i=\max\{pre_i\}+a_i$$

    其中 \(f_i\) 为从最开始到进行完第 \(i\) 项任务所需的时间, \(pre_i\)\(i\) 号结点的前驱数组, \(a_i\) 为做第 \(i\) 件事所需的时间。

    但是,我们如果直接进行 dfs 遍历,可能会出现一个问题:在我们计算 \(f_i\) 的时候,还存在没有计算过的 \(pre_i\),从而导致结果计算错误。
    那么,我们在计算的时候,应该确保在计算一个结点 \(u\) 时,所有与连向它的点都已经被计算过

    而实现这一过程就利用到:拓扑排序

    const int N=1e5+10;
    vector<int> g[N];
    int din[N];
    int cost[N];
    int f[N];
    int n;
    
    int topo()
    {
        queue<int> q;
        int res=0;
        for(int i=1;i<=n;i++)
            if(!din[i])
            {
                q.push(i);
                f[i]=cost[i];
                res=max(res,f[i]);
            }
    
        while(q.size())
        {
            int t=q.front();
            q.pop();
    
            for(int i=0;i<g[t].size();i++)
            {
                int j=g[t][i];
                f[j]=max(f[j],f[t]+cost[j]);
                res=max(res,f[j]);
    
                if(--din[j] == 0) q.push(j);
            }
        }
        return res;
    }
    
    int main()
    {
        cin>>n;
    
        for(int i=1;i<=n;i++)
        {
            int a,t;
            cin>>a>>cost[i];
            int x;
            while(cin>>x && x)
                g[x].push_back(a),din[a]++;
        }
    
        cout<<topo()<<endl;
    
        //system("pause");
    }
    
  • 相关阅读:
    Selenium等待:sleep、隐式、显式和Fluent
    开源礼节
    IntelliJ中基于文本的HTTP客户端
    Selenium4 IDE特性:弹性测试、循环和逻辑判断
    CF 1400G.Mercenaries 题解【SOSDP 组合数学】
    Educational Codeforces Round 33
    Educational Codeforces Round 32
    Educational Codeforces Round 31
    Educational Codeforces Round 30
    Educational Codeforces Round 29
  • 原文地址:https://www.cnblogs.com/fxh0707/p/13595297.html
Copyright © 2011-2022 走看看