题目链接:https://vjudge.net/problem/HDU-5098
题意:给软件安装清单,有些软件需要一些软件安装之前安装。每个软件安装前可能需要重启也可能不需要,问最少需要重启几次。
处理完字符串以后DFS,找一条需要重启的软件安装链中最长的。
gao()大法好。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 2020; 5 char tmp[maxn]; 6 map<string, int> id; 7 int G[maxn][maxn]; 8 int in[maxn]; 9 int rebot[maxn]; 10 int icnt; 11 int dp[maxn]; 12 13 void gao() { 14 string a, b; 15 bool rflag = 0; 16 int k; 17 for(k = 0; tmp[k]; k++) { 18 if(tmp[k] == ':') break; 19 a += tmp[k]; 20 } 21 if(a[a.length()-1] == '*') { 22 rflag = 1; 23 a = a.substr(0, a.length()-1); 24 } 25 if(id.find(a) == id.end()) { 26 id[a] = icnt++; 27 } 28 if(rflag) rebot[id[a]] = 1; 29 int i = k + 2; 30 while(tmp[i]) { 31 b = ""; 32 int j = i; 33 while(tmp[j] != ' ' && tmp[j]) j++; 34 for(int l = i; l < j; l++) b += tmp[l]; 35 if(b != "") { 36 if(id.find(b) == id.end()) { 37 cout << b << " " << icnt << endl; 38 id[b] = icnt++; 39 } 40 G[id[b]][id[a]] = 1; 41 in[id[a]]++; 42 } 43 i = j + 1; 44 } 45 memset(tmp, 0, sizeof(tmp)); 46 } 47 48 int dfs(int u) { 49 if(dp[u] != -1) return dp[u]; 50 int ret = 0; 51 for(int v = 0; v < icnt; v++) { 52 if(!G[u][v]) continue; 53 ret = max(ret, dfs(v)); 54 } 55 return dp[u] = ret + rebot[u]; 56 } 57 58 int main() { 59 // freopen("in", "r", stdin); 60 int T, _ = 1; 61 scanf("%d", &T); 62 getchar(); 63 getchar(); 64 while(T--) { 65 printf("Case %d: ", _++); 66 memset(G, 0, sizeof(G)); 67 memset(rebot, false, sizeof(rebot)); 68 memset(in, 0, sizeof(in)); 69 memset(dp, -1, sizeof(dp)); 70 id.clear(); icnt = 0; 71 while(gets(tmp) && strcmp(tmp, "")) gao(); 72 int ret = 0; 73 for(int i = 0; i < icnt; i++) { 74 if(in[i] == 0) { 75 ret = max(ret, dfs(i)); 76 } 77 } 78 printf("%d ", ret); 79 } 80 return 0; 81 }