Substring CodeForces - 919D
http://codeforces.com/problemset/problem/919/D
就是先判环,如果有环就-1,否则对每个字母分开跑一下dp
错误记录:
1.有向图判环,自环一定要特判!(不能直接用强连通)
2.思考的时候很容易跑偏,去想把各个字母合在一起dp,不知道为什么?
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #include<queue> 5 #include<cstring> 6 using namespace std; 7 struct E 8 { 9 int to,nxt; 10 }e[300100]; 11 int f1[300100],ne,sccc,sccnum[300100],top,dfn[300100],dfsc,low[300100]; 12 int s[300100],n,m; 13 void me(int u,int v) 14 { 15 e[++ne].to=v; 16 e[ne].nxt=f1[u]; 17 f1[u]=ne; 18 } 19 20 void dfs(int u) 21 { 22 low[u]=dfn[u]=++dfsc; 23 s[++top]=u; 24 for(int k=f1[u],v;k!=0;k=e[k].nxt) 25 { 26 v=e[k].to; 27 if(!dfn[v]) 28 { 29 dfs(v); 30 low[u]=min(low[u],low[v]); 31 } 32 else if(!sccnum[v]) 33 low[u]=min(low[u],dfn[v]); 34 } 35 if(low[u]==dfn[u]) 36 { 37 sccc++; 38 while(top&&s[top]!=u) sccnum[s[top--]]=sccc; 39 sccnum[s[top--]]=sccc; 40 } 41 } 42 char ss[300100]; 43 int ans[300100],in[300100],in2[300100],anss; 44 queue<int> q; 45 int main() 46 { 47 int c1,c2,i,k,t;char cc; 48 scanf("%d%d%s",&n,&m,ss+1); 49 for(i=1;i<=m;i++) 50 { 51 scanf("%d%d",&c1,&c2); 52 if(c1==c2) 53 { 54 puts("-1"); 55 return 0; 56 } 57 me(c1,c2);in2[c2]++; 58 } 59 for(i=1;i<=n;i++) 60 if(!dfn[i]) 61 dfs(i); 62 if(sccc!=n) 63 { 64 puts("-1"); 65 return 0; 66 } 67 for(cc='a';cc<='z';cc++) 68 { 69 memset(ans,0,sizeof(ans)); 70 memcpy(in,in2,sizeof(in)); 71 for(i=1;i<=n;i++) 72 if(!in[i]) 73 q.push(i); 74 while(!q.empty()) 75 { 76 t=q.front();q.pop();ans[t]+=ss[t]==cc; 77 anss=max(anss,ans[t]); 78 for(k=f1[t];k;k=e[k].nxt) 79 { 80 in[e[k].to]--;ans[e[k].to]=max(ans[e[k].to],ans[t]); 81 if(!in[e[k].to]) q.push(e[k].to); 82 } 83 } 84 } 85 printf("%d",anss); 86 return 0; 87 }