思路:
拓扑排序过程中dp。若图有环,返回-1。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 300005; 4 vector<int> G[MAXN]; 5 int in[MAXN], n, m; 6 string value; 7 int dp[MAXN][26]; 8 bool solve() 9 { 10 queue<int> q; 11 for (int i = 1; i <= n; i++) 12 { 13 if (!in[i]) 14 { 15 q.push(i); dp[i][value[i - 1] - ‘a‘] = 1; 16 } 17 } 18 while (!q.empty()) 19 { 20 int x = q.front(); q.pop(); 21 for (int i = 0; i < G[x].size(); i++) 22 { 23 int to = G[x][i]; 24 for (int k = 0; k < 26; k++) 25 { 26 if (k == value[to - 1] - ‘a‘) dp[to][k] = max(dp[to][k], dp[x][k] + 1); 27 else dp[to][k] = max(dp[to][k], dp[x][k]); 28 } 29 in[to]--; 30 if (!in[to]) q.push(to); 31 } 32 } 33 for (int i = 1; i <= n; i++) if (in[i]) return false; 34 return true; 35 } 36 int main() 37 { 38 int x, y; 39 cin >> n >> m >> value; 40 set<pair<int, int>> s; 41 bool flg = true; 42 for (int i = 0; i < m; i++) 43 { 44 cin >> x >> y; 45 if (x == y) flg = false; 46 pair<int, int> p(x, y); 47 s.insert(p); 48 } 49 if (!flg) { cout << -1 << endl; return 0; } 50 for (auto p: s) { G[p.first].push_back(p.second); in[p.second]++; } 51 if (!solve()) cout << -1 << endl; 52 else 53 { 54 int maxn = 0; 55 for (int i = 1; i <= n; i++) 56 { 57 for (int j = 0; j < 26; j++) 58 maxn = max(maxn, dp[i][j]); 59 } 60 cout << maxn << endl; 61 } 62 return 0; 63 }