zoukankan      html  css  js  c++  java
  • 最大团问题

    https://vjudge.net/problem/UVA-11324

    把每个强连通分量缩成一个点,构造新图

    在新图上搞个记忆化搜索

    施工完毕

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #include<vector>
    using namespace std;
    const int maxn = 1007;
    stack<int>S;
    int dfn[maxn], low[maxn], sccno[maxn], val[maxn], dp[maxn], scc_cnt, dfs_cnt;
    vector<int>G[maxn], M[maxn];
    void tarjan(int u){
        dfn[u] = low[u] = ++dfs_cnt;
        S.push(u);
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            if(!dfn[v]){
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(!sccno[v]){
                low[u] = min(low[u], dfn[v]);
            }
        }
        if(low[u] == dfn[u]){
            scc_cnt++;
            while(1){
                int tmp = S.top();
                S.pop();
                sccno[tmp] = scc_cnt;
                if(tmp == u)
                    break;
            }
        }
    }
    void findscc(int n){
        memset(dfn, 0, sizeof dfn);
        memset(sccno, 0, sizeof sccno);
        scc_cnt = dfs_cnt = 0;
        for(int i = 1; i <= n; i++){
            if(!dfn[i])
                tarjan(i);
        }
    }
    void test(int n){
        for(int i = 1; i <= n; i++){
            printf("%d ", sccno[i]);
        }
    }
    int treedp(int u){
        if(dp[u] != -1)
            return dp[u];
        dp[u] = val[u];
        int det = 0;
        for(int i = 0; i < M[u].size(); i++){
            int v = M[u][i];
            det = max(det, treedp(v));
        }
        dp[u] += det;
        return dp[u];
    }
    int solve(int n){
        memset(val, 0, sizeof val);
        for(int i = 1; i <= n; i++){
            val[sccno[i]]++;
        }
        for(int i = 1; i <= scc_cnt; i++)
            M[i].clear();
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < G[i].size(); j++){
                int v = G[i][j];
                if(sccno[i] != sccno[v])
                    M[sccno[i]].push_back(sccno[v]);
            }
        }
        memset(dp, -1, sizeof dp);
        int ans = 0;
        for(int i = 1; i <= scc_cnt; i++){
            if(dp[i] == -1){
                ans = max(ans, treedp(i));
            }
        }
        return ans;
    }
    int main(){
        int t;
        scanf("%d", &t);
        while(t--){
            int n, m;
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i++)
                G[i].clear();
            while(m--){
                int u, v;
                scanf("%d%d", &u, &v);
                G[u].push_back(v);
            }
            findscc(n);
            //test(n);
            printf("%d
    ", solve(n));
        }
        return 0;
    }
    
    /*
    4 5 5 1 2 2 3 3 1 4 1 5 2 5 5 1 2 2 3 3 1 4 1 5 2 5 5 1 2 2 3 3 1 4 1 5 2 5 5 1 2 2 3 3 1 4 1 5 2
    */
    搞图论是没有用的,转行做数学题了hh
  • 相关阅读:
    oracle
    mysql的必知技巧
    sql_update
    sql查询
    Java 动态页面技术 之 jsp
    Java 会话技术 之 session
    Java 会话技术 之cookie
    Java HttpServletRequest
    Java HttpServletResponse
    Java Servlet接口、web.xml配置、HttpServlet父类
  • 原文地址:https://www.cnblogs.com/DearDongchen/p/7772840.html
Copyright © 2011-2022 走看看