zoukankan      html  css  js  c++  java
  • uva 11324 The Largest Clique(图论-tarjan,动态规划)

    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


    题目大意:

    T组測试数据。给一张有向图G。求一个结点数最大的结点集,使得该结点中随意两个结点 u 和 v满足:要么 u 能够到达 v。 要么 v 能够到达 u(u 和 v 相互可达也能够)。


    解题思路:

    ”同一个强连通分量中的点要么都选,要么不选。把强连通分量收缩点后得到SCC图。让每一个SCC结点的权等于它的结点数,则题目转化为求SCC图上权最大的路径。因为SCC图是一个 DAG, 能够用动态规划求解。



    解题代码:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1100;
    const int maxm=51000;
    
    struct edge{
        int u,v,next;
        edge(int u0=0,int v0=0){
            u=u0;v=v0;
        }
    }e[maxm];
    
    int n,m,head[maxn],dfn[maxn],low[maxn],mark[maxn],w[maxn],color[maxn],dp[maxn],cnt,nc,index;
    vector <int> vec;
    vector <vector<int> > dfsmap;
    
    void addedge(int u,int v){
        e[cnt]=edge(u,v);e[cnt].next=head[u];head[u]=cnt++;
    }
    
    void input(){
        cnt=nc=index=0;
        scanf("%d%d",&n,&m);
        vec.clear();
        for(int i=0;i<=n;i++){
            w[i]=dfn[i]=0;
            mark[i]=false;
            color[i]=dp[i]=head[i]=-1;
        }
        int u,v;
        while(m-- >0){
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
    }
    
    void tarjan(int s){
        dfn[s]=low[s]=++index;
        mark[s]=true;
        vec.push_back(s);
        for(int i=head[s];i!=-1;i=e[i].next){
            int d=e[i].v;
            if(!dfn[d]){
                tarjan(d);
                low[s]=min(low[d],low[s]);
            }else if(mark[d]){
                low[s]=min(low[s],dfn[d]);
            }
        }
        if(dfn[s]==low[s]){
            nc++;
            int d;
            do{
                d=vec.back();
                vec.pop_back();
                color[d]=nc;
                mark[d]=false;
                w[nc]++;
            }while(d!=s);
        }
    }
    
    int DP(int s){
        if(dp[s]!=-1) return dp[s];
        int ans=w[s];
        for(int i=0;i<dfsmap[s].size();i++){
            int d=dfsmap[s][i];
            if(DP(d)+w[s]>ans) ans=DP(d)+w[s];
        }
        return dp[s]=ans;
    }
    
    void solve(){
        for(int i=1;i<=n;i++){
            if(!dfn[i]) tarjan(i);
        }
        dfsmap.clear();
        dfsmap.resize(nc+1);
        for(int i=0;i<cnt;i++){
            int x=color[e[i].u],y=color[e[i].v];
            if(x!=y){
                dfsmap[x].push_back(y);
                //cout<<x<<"->"<<y<<endl;
            }
        }
        int ans=0;
        for(int i=1;i<=nc;i++){
            if(DP(i)>ans) ans=DP(i);
            //cout<<i<<" "<<ans<<endl;
        }
        printf("%d
    ",ans);
    }
    
    int main(){
        int t;
        scanf("%d",&t);
        while(t-- >0){
            input();
            solve();
        }
        return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    配置Yaf
    计算机科学中最重要的32个算法
    mysql show status详解
    Structs 在Struts.xml中配置action时,action的name属性最好首字母大写
    MyEclipse创建ssh项目和连接数据库
    Myeclipse安装svn插件
    win7安装ubuntu双系统
    Java查看API和源码的方法
    华为oj平台的新网址
    详细解析Java中抽象类和接口的区别
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4837229.html
Copyright © 2011-2022 走看看