uva 11324 The Largest Clique (Tarjan+记忆化)
/*每个环 要么不选 要么全选 可缩点 就得到一个GAD图 然后搞搞算出最大路径*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100010 using namespace std; int T,n,m,num,head[maxn],low[maxn],dfn[maxn],s[maxn],top,vi[maxn]; int sum,belong[maxn],Head[maxn],Num,ans,f[maxn],topt,dp[maxn]; struct node{int v,pre;}e[maxn]; struct Node{int v,pre;}E[maxn]; void add(int from,int to) { e[num].v=to; e[num].pre=head[from]; head[from]=num++; } void Add(int from,int to) { E[Num].v=to; E[Num].pre=Head[from]; Head[from]=Num++; } void Tarjan(int x) { low[x]=dfn[x]=++topt; s[++top]=x;f[x]=1; for(int i=head[x];i!=-1;i=e[i].pre) { int v=e[i].v; if(dfn[v]==0) { Tarjan(v);low[x]=min(low[x],low[v]); } else if(f[v])low[x]=min(low[x],dfn[v]); } if(low[x]==dfn[x]) { sum++; while(x!=s[top]) { f[s[top]]=0;belong[s[top]]=sum;top--;vi[sum]++; } f[s[top]]=0;belong[s[top]]=sum;top--;vi[sum]++; } } int Dfs(int x) { if(dp[x])return dp[x]; int r=0; for(int i=Head[x];i!=-1;i=E[i].pre) { int v=E[i].v; r=max(r,Dfs(v)); } return dp[x]=r+vi[x]; } int main() { scanf("%d",&T); while(T--) { memset(belong,0,sizeof(belong)); memset(head,-1,sizeof(head)); memset(Head,-1,sizeof(Head)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(dp,0,sizeof(dp)); memset(vi,0,sizeof(vi)); memset(f,0,sizeof(f)); memset(s,0,sizeof(s)); num=Num=topt=sum=ans=0; int u,v; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v); } for(int i=1;i<=n;i++) if(dfn[i]==0) Tarjan(i); for(int u=1;u<=n;u++) for(int i=head[u];i!=-1;i=e[i].pre) { int U=belong[u],V=belong[e[i].v]; if(U!=V)Add(U,V); } for(int i=1;i<=sum;i++) ans=max(ans,Dfs(i)); printf("%d\n",ans); } }