题意: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\n", ans); return 0; }