CF919D Substring

本文介绍了一种结合拓扑排序与动态规划(DP)的算法实现思路,用于解决图中存在环的情况,并通过示例代码详细展示了算法的具体实现过程。适用于解决依赖关系问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

拓扑排序过程中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 }

 

转载于:https://www.cnblogs.com/wangyiming/p/8463581.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值