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);
      }
}

 

posted @ 2016-08-24 09:16  一入OI深似海  阅读(239)  评论(0编辑  收藏  举报