zoukankan      html  css  js  c++  java
  • Uva 11324 The Largest Clique 缩点 求最大团

    Problem B: The Largest Clique

    Given a directed graph G, consider the following transformation. First, create a new graph T(G) to have the same vertex set as G. Create a directed edge between two vertices u and v in T(G) if and only if there is a path between u and v in G that follows the directed edges only in the forward direction. This graph T(G) is often called the transitive closure of G.

    We define a clique in a directed graph as a set of vertices U such that for any two vertices u and v in U, there is a directed edge either from u to v or from v to u (or both). The size of a clique is the number of vertices in the clique.

    The number of cases is given on the first line of input. Each test case describes a graph G. It begins with a line of two integers n and m, where 0 ≤ n ≤ 1000 is the number of vertices of G and 0 ≤ m ≤ 50,000 is the number of directed edges of G. The vertices of G are numbered from 1 to n. The following m lines contain two distinct integers u and v between 1 and n which define a directed edge from u to v in G.

    For each test case, output a single integer that is the size of the largest clique in T(G).

    Sample input

    1
    5 5
    1 2
    2 3
    3 1
    4 1
    5 2
    

    Output for sample input

    4
    

    Zachary Friggstad

    -----------------------------------------

    缩点,求最大团

    -----------------------------------------

    #include <iostream>
    #include <vector>
    #include <stack>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn=1111;
    const int INF=1e8;
    
    void dfs(int u);//搜索求强连通
    void find_scc(int n);//求强连通
    void tops(int n);//拓扑排序
    
    int w[maxn];//点权
    vector<int>a[maxn];//DAG图
    vector<int>G[maxn];//原图
    int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;//Tarjan
    stack<int> S;//Tarjan
    int indegree[maxn];//入度
    int ans;
    bool hash[maxn][maxn];
    //-----Tarjan------
    
    void dfs(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        int len=G[u].size();
        for (int i=0;i<len;i++)
        {
            int v=G[u][i];
            if (!pre[v])
            {
                dfs(v);
                lowlink[u]=min( lowlink[u], lowlink[v] );
            }
            else if (!sccno[v])
            {
                lowlink[u]=min( lowlink[u], pre[v] );
            }
        }
        if (lowlink[u]==pre[u])
        {
            scc_cnt++;
            while (true)
            {
                int x=S.top();
                S.pop();
                sccno[x]=scc_cnt;
                w[scc_cnt]++;
                if (x==u) break;
            }
        }
    }
    void find_scc(int n)
    {
        dfs_clock=scc_cnt=0;
        memset(sccno,0,sizeof(sccno));
        memset(pre,0,sizeof(pre));
        memset(w,0,sizeof(w));
        while (!S.empty()) S.pop();
        for (int i=1;i<=n;i++)
        {
            if (!pre[i]) dfs(i);
        }
    }
    
    
    int f[maxn];
    int DP(int u)
    {
        int ret=0;
        int sz=a[u].size();
        for (int i=0;i<sz;i++)
        {
            int v=a[u][i];
            ret=max(ret,DP(v));
        }
        f[u]=ret+w[u];
        return f[u];
    }
    
    
    //-----------------
    
    int main()
    {
        int T;
        int n,m;
        scanf("%d",&T);
        while (T--)
        {
            //init()
            memset(indegree,0,sizeof(indegree));
            memset(hash,0,sizeof(hash));
            memset(f,0,sizeof(f));
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
            {
                G[i].clear();
                a[i].clear();
            }
            for (int i=1;i<=m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                G[u].push_back(v);
            }
            //强连通
            find_scc(n);
            //缩点
            for (int i=1;i<=n;i++)
            {
                int sz=G[i].size();
                for (int j=0;j<sz;j++)
                {
                    int v=G[i][j];
                    if (sccno[i]!=sccno[v]&&!hash[sccno[i]][sccno[v]])
                    {
                        a[sccno[i]].push_back(sccno[v]);
                        hash[sccno[i]][sccno[v]]=true;
                        indegree[sccno[v]]++;
                    }
                }
            }
            ans=0;
            for (int i=1;i<=n;i++)
            {
                if (indegree[i]==0)
                {
                    ans=max(ans,DP(i));
                }
            }
    
            //输出
            printf("%d\n",ans);
        }
        return 0;
    }






  • 相关阅读:
    跨域导致FormsAuthentication.Decrypt报错:填充无效,无法被移除
    Php构造函数construct的前下划线是双的_
    DNN学习资源整理
    改进housemenu2使网站导航亲Seo并在新窗口中打开。
    推荐10款非常优秀的 HTML5 开发工具
    Ext.Net系列:安装与使用
    Devexpress 破解方法
    Microsoft Visual Studio 2010 遇到了异常,可能是由某个扩展导致的
    浮躁和互联网
    chrome 默认以 https打开网站
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226324.html
Copyright © 2011-2022 走看看