LRJ白书图论 11324 - The Largest Clique uva

来源:互联网 发布:o2o源码开发 编辑:程序博客网 时间:2024/05/16 07:27

/*    题意:给一张有向图,求这样的一个点集,使得集合中的点u,v,u->v,or v->u,or,u<->v。   对图缩点,构造一张DAG。在DAG上作dp最长路。  点权为每个强连通分量重节点的个数。*/#include <stdio.h>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn=1010;const int maxm=50001;struct edge{    int to,next;} e[maxm];vector<int> map[maxn];int head[maxn],low[maxn],stack[maxn],dfn[maxn],belong[maxn],dp[maxn],num[maxn];bool vis[maxn];int n,t,scnt,top,cnt;void add(int i,int j){    e[t].next=head[i];    e[t].to=j;    head[i]=t++;}void tarjan(int u){    int tt;    dfn[u]=low[u]=++cnt;    stack[top++]=u;    vis[u]=true;    for(int i=head[u]; i!=-1; i=e[i].next)    {        int j=e[i].to;        if(!dfn[j])        {            tarjan(j);            low[u]=min(low[u],low[j]);        }        else if(vis[j])            low[u]=min(low[u],low[j]);    }    if(low[u]==dfn[u])    {        scnt++;        do        {            tt=stack[--top];            belong[tt]=scnt;            vis[tt]=false;        }        while(u!=tt);    }}int f(int u){    if(dp[u]) return dp[u];    int ans=0;    for(int i=0; i<(int)map[u].size(); i++)        ans=max(ans,f(map[u][i]));    return dp[u]=ans+num[u];}int main(){    int T,m,a,b;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        memset(belong,0,sizeof(belong));        memset(low,0,sizeof(low));        memset(dfn,0,sizeof(dfn));        memset(stack,0,sizeof(stack));        memset(vis,false,sizeof(vis));        memset(dp,0,sizeof(dp));        memset(num,0,sizeof(num));        top=0;        cnt=scnt=t=0;        while(m--)        {            scanf("%d%d",&a,&b);            add(a,b);        }        for(int i=1; i<=n; i++)        {            if(!dfn[i]) tarjan(i);        }        memset(vis,false,sizeof(vis));        for(int i=1; i<=scnt; i++) map[i].clear();        for(int i=1; i<=n; i++)        {            for(int j=head[i]; j!=-1; j=e[j].next)            {                int u=e[j].to;                if(belong[i]!=belong[u])                {                    map[belong[i]].push_back(belong[u]);                    vis[belong[u]]=true;//从入度为0点开始搜                }            }            num[belong[i]]++;        }        int ans=0;        for(int i=1; i<=scnt; i++)            if(!vis[i]) ans=max(ans,f(i));        printf("%d\n",ans);    }    return 0;}


原创粉丝点击