题目链接: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\n",toposort()); 58 return 0; 59 }