首页 > 代码库 > UVA11324 The Largest Clique[强连通分量 缩点 DP]

UVA11324 The Largest Clique[强连通分量 缩点 DP]

UVA - 11324
The Largest Clique

 

题意:求一个节点数最大的节点集,使任意两个节点至少从一个可以到另一个

 


同一个SCC要选一定全选

求SCC 缩点建一个新图得到一个DAG,直接DP行了

这个新图不需要判重边,重边就是真实存在

 

////  main.cpp//  最大团////  Created by Candy on 02/11/2016.//  Copyright © 2016 Candy. All rights reserved.//#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define C(x) memset(x,0,sizeof(x))using namespace std;const int N=1e3+5,M=5e4+5;inline int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1;c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}    return x*f;}int T,n,m,u,v;struct edge{    int v,ne;}e[M];int h[N],cnt=0;inline void ins(int u,int v){    cnt++;    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;}int dfn[N],low[N],belong[N],dfc,scc,size[N];int st[N],top;void dfs(int u){    dfn[u]=low[u]=++dfc;    st[++top]=u;    for(int i=h[u];i;i=e[i].ne){        int v=e[i].v;        if(!dfn[v]){            dfs(v);            low[u]=min(low[u],low[v]);        }else if(!belong[v])                low[u]=min(low[u],dfn[v]);    }    if(low[u]==dfn[u]){        scc++;        while(true){            int x=st[top--];            belong[x]=scc;            size[scc]++;            if(x==u) break;        }    }}void SCC(){    dfc=scc=0;    C(dfn);C(low);C(belong);C(size);    top=0;    for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);}edge es[N];int hs[N],cs=0;inline void inss(int u,int v){    cs++;    es[cs].v=v;es[cs].ne=hs[u];hs[u]=cs;}void buildGraph(){    cs=0;    C(hs);    for(int u=1;u<=n;u++){        int a=belong[u];        for(int i=h[u];i;i=e[i].ne){            int b=belong[e[i].v];            if(a!=b) inss(a,b);        }    }}int f[N];int dp(int u){    if(f[u]!=-1) return f[u];    f[u]=size[u];    int mx=0;    for(int i=hs[u];i;i=es[i].ne){        int v=es[i].v;//printf("dp %d v %d\n",u,v);        mx=max(mx,dp(v));    }    return f[u]+=mx;}int main(int argc, const char * argv[]) {    T=read();    while(T--){        n=read();m=read();        cnt=0;memset(h,0,sizeof(h));        for(int i=1;i<=m;i++){u=read();v=read();ins(u,v);}        SCC();        buildGraph();                memset(f,-1,sizeof(f));        int ans=0;        for(int i=1;i<=scc;i++){            if(f[i]==-1) dp(i);            ans=max(ans,f[i]);        }        printf("%d\n",ans);    }        return 0;}

 

UVA11324 The Largest Clique[强连通分量 缩点 DP]