1. 程式人生 > >DAG上DP--CF919D

DAG上DP--CF919D

某谷DAGDAGDPDP,但是要先tarjantarjan判一下強聯通分量,有的話輸出1-1f[i][j]f[i][j]表示到ii節點jj的最大出現次數,然後按照tuoputuopu排序dpdp轉移就好了 (注意有自環) 放上我的程式碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 300005
using namespace
std; int n,m,cnt,head[N],dfn[N],low[N],num,stk[N],top,f[N][30],ans,d[N]; bool vis[N],flg; char s[N]; inline int rd(){ int x=0,f=1;char c=' '; while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar(); while(c<='9' && c>='0') x=x*10+c-'0',c=getchar(); return x*f; } struct EDGE{ int to,nxt;
}edge[N<<1]; inline void add(int x,int y){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } inline void tarjan(int u){ vis[u]=1; dfn[u]=low[u]=++num; stk[++top]=u; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); }
else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ int tmp,cc=0; do{ tmp=stk[top--]; vis[tmp]=0; cc++; }while(u!=tmp); if(cc>1) flg=true; } return; } inline void tuopu(){ top=0; for(int i=1;i<=n;i++) if(!d[i]) stk[++top]=i,f[i][s[i]-'a'+1]=1; while(top){ int u=stk[top--]; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; d[v]--; if(!d[v]) stk[++top]=v; int ch=s[v]-'a'+1; f[v][ch]=max(f[v][ch],f[u][ch]+1); for(int j=1;j<=26;j++) f[v][j]=max(f[v][j],f[u][j]); } } } int main(){ n=rd(); m=rd(); scanf("%s",s+1); for(int i=1;i<=m;i++){ int x=rd(),y=rd(); if(x==y) flg=true; add(x,y); d[y]++; } for(int i=1;i<=n;i++) if(!dfn[i]) { tarjan(i); if(flg) return puts("-1"),0; } tuopu(); for(int i=1;i<=n;i++) for(int j=1;j<=26;j++) ans=max(ans,f[i][j]); printf("%d\n",ans); return 0; }

還有和Monster_QiMonster\_Qi同時做這道題居然時間空間一模一樣 果然是母子 在這裡插入圖片描述