• Codeforces Round #455 (Div. 2) E. Coprocessor DAG图上dp


    E. Coprocessor

    题意:n 个任务,每个任务在 主 / 副 处理器上执行。每个任务可能依赖于其它的一些任务,副处理器每次可以处理多个任务。但如果一个任务要在副处理器上执行,那它所依赖的任务要么已执行完了,要么和它一起在这个副处理器上同时执行。问副处理器最少调用多少次。

    直白一点讲,就是给出一个 DAG 图,n 个点, m 条边,每个点的权值为 0 或1 。操作:直接相互连通的权值为 1 的点可以一次处理掉。 问最少操作多少次。

    tags:因为是DAG 图,直接跑 dp

    dp[i] 表示第 i 个点最少的操作次数,设 i 可以到 to 点,则 dp[i] = min(dp[i],  dp[to]+(a[i]==0 && dp[i]==1)) 。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 100005;
    
    int n, m, a[N], dp[N], in[N], ans;
    vector< int > G[N];
    bool  vis[N];
    void solve(int u)
    {
        if(G[u].size()==0 && a[u] && !vis[u]) ++dp[u];
        vis[u] = true;
        for(auto to : G[u])
        {
            if(!vis[to]) solve(to);
            dp[u] = max(dp[u], dp[to]+(a[u] && a[to]==0));
        }
        ans = max(ans, dp[u]);
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        rep(i,0,n-1) scanf("%d", &a[i]);
        int u, v;
        rep(i,1,m)
        {
            scanf("%d%d", &u, &v);
            G[u].PB(v);
            ++in[v];
        }
        rep(i,0,n-1)
            if(in[i]==0) solve(i);
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    作业5

    Linux系统管理4
    作业
    递归训练1:在两个长度相等的排序数组中找到上中位数
    LeetCode:面试题 08.05. 递归乘法
    LeetCode:面试题 08.06. 汉诺塔问题
    LeetCode:22. 括号生成
    如何仅用递归函数和栈操作逆序一个栈
    LeetCode:面试题 03.02. 栈的最小值
  • 原文地址:https://www.cnblogs.com/sbfhy/p/8178222.html
Copyright © 2020-2023  润新知