UVA -- 11324 The Largest Clique(强连通+记忆化搜索)

来源:互联网 发布:宝可梦图鉴软件 编辑:程序博客网 时间:2024/04/29 19:30

题目大意:给出m对点的关系,要求出在一个图中任意两点有路径相连的点的个数;

思路分析:一个强连通分量里的任意两点都是有边相连的,把连通分量缩成一个点,重新构图(不同连通分量构成的图),用记忆化搜缩求最长的路径;

代码实现:

#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#include<iostream>#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define MEM(a) (memset((a),0,sizeof(a)))#define MEME(a) (memset((a),-1,sizeof(a)))#define MEMX(a) (memset((a),0x3f,sizeof(a)))using namespace std;const int N=1005;int dfn[N],low[N],st[N],in[N],belong[N],s_sum[N],dp[N],bcnt,top,s_top,tim,n,m;bool inst[N];vector<int> v[N];struct Edge{    int to;    Edge *next;}*head[N],e[50005];void Addedege(int from,int to){    Edge *p=&e[top++];    p->to=to;    p->next=head[from];    head[from]=p;}void Tarjan(int i){    dfn[i]=low[i]=++tim;    st[++s_top]=i;    inst[i]=1;    int to;    for(Edge *p=head[i];p;p=p->next){        to=p->to;        if(!dfn[to]){            Tarjan(to);            if(low[to]<low[i]) low[i]=low[to];        }else if(inst[to]&&dfn[to]<low[i]) low[i]=dfn[to];    }    if(dfn[i]==low[i]){        bcnt++;        do{            to=st[s_top--];            inst[to]=0;            belong[to]=bcnt;            s_sum[bcnt]++;        }while(i!=to);    }}int dfs(int i){    int& ans=dp[i];    if(ans>0) return ans;    ans=s_sum[i];    for(int j=0;j<v[i].size();++j)        ans=Max(ans,dfs(v[i][j])+s_sum[i]);    return ans;}int main(){    int t,p1,p2;    scanf("%d",&t);    while(t--){        MEM(head),MEM(dfn),MEM(low),MEM(inst),MEM(in),MEM(dp),MEM(s_sum);        bcnt=top=s_top=tim=0;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;++i) v[i].clear();        int max_sum=0;        while(m--){            scanf("%d%d",&p1,&p2);            Addedege(p1,p2);        }        for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);        for(int i=1;i<=n;++i)            for(Edge *p=head[i];p;p=p->next)                if(belong[i]!=belong[p->to]) v[belong[i]].push_back(belong[p->to]),in[belong[p->to]]=1;        for(int i=1;i<=bcnt;++i){            if(!in[i])                max_sum=Max(max_sum,dfs(i));        }        printf("%d\n",max_sum);    }}


0 0