• 训练赛 Grouping(强连通分量缩点 + DAG求最长路)


    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=158#problem/F


    大致题意:给出n个人和m种关系(ti,si),表示ti的年龄不小于si。问最小能被划分为几个集合。每一个集合都要满足里面的人都无法比較。


    思路:对于一条路上的点。它们必然不能被划分到同一个集合中,因此原题变为求一条最长路。

    而题目中有可能出现环。因此,先tarjan缩点转化为DAG,而缩点后的每一个点的点权便是该节点中包括的点的个数。然后记忆化求最长路。

    PS:该题与上一篇 

    uva 11324 The Largest Clique是一样的。该题重在转化。


    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #define LL long long
    #define _LL __int64
    #define eps 1e-8
    #define PI acos(-1.0)
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int maxn = 100010;
    
    vector <int> edge[maxn],edge2[maxn];
    int n,m;
    int dfn[maxn],low[maxn],instack[maxn],dep,scc;
    stack <int> st;
    int set[maxn],num[maxn];
    int d[maxn];
    
    void init()
    {
        for(int i = 1; i <= n; i++)
        {
            edge[i].clear();
            edge2[i].clear();
        }
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(instack,0,sizeof(instack));
        while(!st.empty()) st.pop();
    
        dep = 0;
        scc = 0;
        memset(num,0,sizeof(num));
        memset(d,0,sizeof(d));
    }
    
    void tarjan(int u)
    {
        dfn[u] = low[u] = ++dep;
        instack[u] = 1;
        st.push(u);
    
        for(int i = 0; i < (int)edge[u].size(); i++)
        {
            int v = edge[u][i];
            if(!dfn[v])
            {
                tarjan(v);
                low[u] = min(low[u],low[v]);
            }
            else if(instack[v])
                low[u] = min(low[u],dfn[v]);
        }
        if(dfn[u] == low[u])
        {
            scc++;
            int t;
            while(1)
            {
                t = st.top();
                st.pop();
                instack[t] = 0;
                set[t] = scc;
                num[scc]++;
                if(t == u)
                    break;
            }
        }
    }
    
    void creat()
    {
        for(int u = 1; u <= n; u++)
        {
            for(int i = 0; i < (int)edge[u].size(); i++)
            {
                int v = edge[u][i];
                if(set[u] != set[v])
                    edge2[set[u]].push_back(set[v]);
            }
        }
    }
    
    int dp(int u)
    {
        if(d[u]) return d[u];
        else if(edge2[u].size() == 0) return d[u] = num[u];
    
        int ans = 0;
        for(int i = 0; i < (int)edge2[u].size(); i++)
        {
            int v = edge2[u][i];
            ans = max(ans,dp(v));
        }
        return d[u] = ans+num[u];
    }
    
    int main()
    {
        int u,v;
        while(~scanf("%d %d",&n,&m))
        {
            init();
            for(int i = 1; i <= m; i++)
            {
                scanf("%d %d",&u,&v);
                edge[u].push_back(v);
            }
            for(int i = 1; i <= n; i++)
                if(!dfn[i])
                    tarjan(i);
    
            creat();
    
            int ans = 0;
            for(int i = 1; i <= scc; i++)
            {
                ans = max(ans,dp(i));
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    



  • 相关阅读:
    git错误操作导致代码丢失找回
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题
    WebMvcConfigurerAdapter在Spring boot2.x已废弃
    AJAX实现模拟注册跳转
    遍历字符串替换实例
    spring boot2.x依赖
    Thymeleaf页面添加th:value后报错原因
    thymeleaf中th:href字符拼接
    刁肥宅数据结构课设“布隆过滤器的实现和应用”源代码(v1.0,永不上交)
    数据结构实验1:C++实现静态顺序表类
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5060808.html
Copyright © 2020-2023  润新知