Codefroces 919D Substring(拓扑排序+DP)

题目链接:http://codeforces.com/problemset/problem/919/D

题目大意:给你一张有向图,给你每个顶点上的字母和一些边,让你找出一条路径,路径上的相同字母数最多,输出最大相同字母数,若可以无穷多则输出-1(成环)。

解题思路:因为是有向图,所以可以直接利用拓扑排序,拓扑排序过程中用f[i][j]记录到第i个点为止的路径,出现字母j的最大出现次数即可。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstring>
 6 #include<algorithm> 
 7 using namespace std;
 8 const int N=3e5+5;
 9 
10 int n,m;
11 int f[N][26],deg[N];
12 char ch[N];
13 vector<int>v[N];
14 
15 int toposort(){
16     queue<int>q;
17     int ans=-1;
18     for(int i=1;i<=n;i++){
19         if(deg[i]==0)
20             q.push(i);
21     }
22     int cnt=0;
23     while(!q.empty()){
24         int k=q.front();
25         q.pop();
26         cnt++;
27         f[k][ch[k]-'a']++;
28         ans=max(f[k][ch[k]-'a'],ans);
29         for(int i=0;i<v[k].size();i++){
30             int t=v[k][i];
31             deg[t]--;
32             for(int j=0;j<26;j++){
33                 f[t][j]=max(f[t][j],f[k][j]);
34             }
35             if(deg[t]==0){
36                 q.push(t);
37             }        
38         }
39     }
40     if(cnt!=n)
41         ans=-1;
42     return ans;
43 }
44 
45 int main(){
46     scanf("%d%d",&n,&m);
47     getchar();
48     for(int i=1;i<=n;i++){
49         scanf("%c",&ch[i]);
50     }
51     for(int i=1;i<=m;i++){
52         int a,b;
53         scanf("%d%d",&a,&b);
54         deg[b]++;
55         v[a].push_back(b);
56     }
57     printf("%d
",toposort());
58     return 0;
59 }
原文地址:https://www.cnblogs.com/fu3638/p/8412701.html