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


    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
    ",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
    ",ans);
        }
        
        return 0;
    }
  • 相关阅读:
    js监听全屏的事件
    java后端发送请求
    java参数转换为javaBean对象
    Cesiumjs初学第一天
    echarts设置toolTip大小和样式问题
    楼梯式导航
    SpringMybatisMapper
    ASP.NET Session丢失的情况
    C# 生成随机数
    c#实现每隔规定时间自动执行程序代码
  • 原文地址:https://www.cnblogs.com/candy99/p/6026101.html
Copyright © 2020-2023  润新知