Codeforces Round #460 (Div. 2) 919D. Substring
阿新 • • 發佈:2018-10-31
- 題目連結
- 大意描述:給定一個n個節點,m條邊的有向圖,每個節點上有一個小寫字母,對於一條路徑,它的值為最常出現的字母的數量,求在圖中所有路徑中,值最大的一條路徑的值。但如果值可以任意大,則輸出-1.
- 演算法:容易得出,如果圖中有環,則需要輸出-1,否則我們列舉最常出現的字母,然後在圖上跑記憶化深搜即可。
-
#include<bits/stdc++.h> #define rep(i,j,k) for(register int i=j;i<=k;i++) using namespace std; template<typename T> void chkmax(T &x,T y){x=max(x,y);} template<typename T> void read(T &num){ char c=getchar();num=0;int f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+(c^48);c=getchar();} num*=f; } template<typename T> void qwq(T x){ if(x>9)qwq(x/10); putchar(x%10+'0'); } template<typename T> void write(T x){ if(x<0){x=-x;putchar('-');} qwq(x);putchar('\n'); } char st[300010]; struct wzy{ int next,vertice; }edge[300010]; int head[300010];int len=0; inline void add_edge(int x,int y){ edge[++len].next=head[x];edge[len].vertice=y;head[x]=len; return; } bool flag=false;bool vis[300010];bool vis2[300010]; inline void dfs(int x){ if(vis[x])return; if(vis2[x]){flag=true;return;} vis2[x]=true; for(int i=head[x];i;i=edge[i].next){ dfs(edge[i].vertice); } vis2[x]=false; vis[x]=true; return; } int f[300010]; inline int dp(int x,char tmp){ if(f[x]!=-1)return f[x]; int re_value=0; for(int i=head[x];i;i=edge[i].next){ chkmax(re_value,dp(edge[i].vertice,tmp)); } f[x]=re_value+(tmp==st[x-1]); return f[x]; } int main(){ int n,m;read(n);read(m); scanf("%s",st); rep(i,1,m){ int x,y;read(x);read(y); add_edge(x,y); } rep(i,1,n){ dfs(i); if(flag==true)break; } if(flag==true){ write(-1);return 0; } int ans=0; for(char i='a';i<='z';i++){ memset(f,-1,sizeof(f)); rep(j,1,n){ chkmax(ans,dp(j,i)); } } write(ans); return 0; }