1. 程式人生 > >Codefroces 919D Substring(拓撲排序+DP)

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

ostream blank ems pro div 最大 拓撲 const 代碼

題目鏈接: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 }

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