Codeforces Round #455 (Div. 2)E. Coprocessor[dfs]
题目:http://codeforces.com/contest/909/problem/E
题意:给一个有向无环图最多1e5条边,每个节点代表一个task,每个task题目会给出需要协处理器或主处理器完成。处理每个任务之前必须处理完他的前驱或者他的前驱也在这一次处理之中,问需要调用多少次协处理器。
分析:记忆化找入度为0的点dfs找最大值就可以,dp[i]表示第i个点以后的点需要的协处理器次数。只需要考虑一点,转移的时候如果后继和当前点都需要协处理器,则可以把他们放在一次处理中,其余情况直接加当前mode转移。
代码:
1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #include<iostream> 4 #include<cstdio> 5 #include<fstream> 6 #include<iomanip> 7 #include<algorithm> 8 #include<cmath> 9 #include<deque> 10 #include<vector> 11 #include<bitset> 12 #include<queue> 13 #include<string> 14 #include<cstring> 15 #include<map> 16 #include<stack> 17 #include<set> 18 #include<functional> 19 #define pii pair<int, int> 20 #define mod 1000000007 21 #define mp make_pair 22 #define pi acos(-1) 23 #define eps 0.00000001 24 #define mst(a,i) memset(a,i,sizeof(a)) 25 #define all(n) n.begin(),n.end() 26 #define lson(x) ((x<<1)) 27 #define rson(x) ((x<<1)|1) 28 #define inf 0x3f3f3f3f 29 typedef long long ll; 30 typedef unsigned long long ull; 31 using namespace std; 32 const int maxn = 1e5 + 5; 33 vector<int>a[maxn]; 34 int in[maxn]; 35 int mode[maxn]; 36 int dp[maxn]; 37 int vis[maxn]; 38 int dfs(int t) 39 { 40 if (dp[t] != -1)return dp[t]; 41 int temp = 0; 42 if (a[t].size() == 0)return dp[t] = mode[t]; 43 for (int i = 0; i < a[t].size(); ++i) 44 { 45 if (mode[a[t][i]] == 1 && mode[t] == 1) 46 temp = max(dfs(a[t][i]), temp); 47 else 48 temp = max(dfs(a[t][i]) + mode[t], temp); 49 } 50 return dp[t] = temp; 51 } 52 int main() 53 { 54 ios::sync_with_stdio(false); 55 cin.tie(0); cout.tie(0); 56 int i, j, k, m, n; 57 cin >> n >> m; 58 int ta, tb; 59 mst(dp, -1); 60 for (int i = 0; i < n; ++i)cin >> mode[i]; 61 for (int i = 1; i <= m; ++i) 62 { 63 cin >> ta >> tb; 64 a[ta].push_back(tb); 65 in[tb]++; 66 } 67 int ans = -1; 68 for (int i = 0; i < n; ++i) 69 { 70 if (in[i] == 0)ans = max(dfs(i), ans); 71 } 72 cout << ans << endl; 73 return 0; 74 }