码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-11-03 14:00:41      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:argc   最大团   memset   uil   efi   namespace   ges   top   space   

UVA - 11324

 

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

 


同一个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]

标签:argc   最大团   memset   uil   efi   namespace   ges   top   space   

原文地址:http://www.cnblogs.com/candy99/p/6026101.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!