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;
}
原文地址:https://www.cnblogs.com/sbfhy/p/8178222.html