zoukankan      html  css  js  c++  java
  • CF 949C Data Center Maintenance_强联通分量_思维题

    题意:
    某土豪公司建立了n个数据中心,把m份资料每份在其中的两个数据中心备份。 每个数据中心在一天h个小时当中有一个小时需要维护,此时不提供资料下载服务。 现在土豪公司想要将其中若干个数据中心的维护时间向后推迟一小时,并要求一天中任意时刻每份资料都可以被下载,问最少选取多少个数据中心维护。

    题解:
    首先,对于两个备份的地方,我们发现只有 (C[a]+1)(C[a]+1) % h==C[b]h==C[b] 时,a,ba,b 两个处理器需要同时后延一小时。于是,建图的条件就是只要 (C[a]+1)(C[a]+1) % h==C[b])h==C[b]) 就在 (a,b)(a,b) 之间连一条边,跑一遍 tarjantarjan 求出出度为 00 的大小最小的团即可。

    Code:

    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<vector>
    using namespace std;
    const int maxn = 1000000 + 5;
    int n,m, h, C[maxn];
    int head[maxn], to[maxn << 1], nex[maxn << 1], cnt, degree[maxn];
    int dfn[maxn], low[maxn], scc, siz[maxn], idx, vis[maxn], answer[maxn], ans;
    stack<int>S;
    inline void get_min(int &a, int b){ if(a > b) a = b;}
    struct Graph{
        inline void add_edge(int u,int v){
            nex[++cnt] = head[u];
            head[u] = cnt;
            to[cnt] = v;
        }
        void tarjan(int u){
            low[u] = dfn[u] = ++scc;
            S.push(u);
            vis[u] = 1;
            for(int v = head[u]; v ; v = nex[v])
            {
                if(!vis[to[v]])
                {
                    tarjan(to[v]);
                    low[u] = min(low[u], low[to[v]]); 
                }
                else if(!answer[to[v]]) get_min(low[u], dfn[to[v]]);
            }
            if(dfn[u] == low[u])
            {
                ++idx;
                for(;;)
                {
                    int x = S.top(); S.pop();
                    answer[x] = idx;
                    ++siz[idx];
                    if(u == x) break;
                }
            }
        }
        inline void solve(){
            siz[0] = maxn;
            for(int i = 1;i <= n; ++i) if(!vis[i]) tarjan(i);
            for(int i = 1;i <= n; ++i)
            {
                for(int j = head[i]; j ; j = nex[j])
                {
                    if(answer[to[j]] != answer[i]) ++degree[answer[i]];
                }
            }
            for(int i = 1;i <= idx; ++i){
                if(degree[i]) continue;
                if(siz[ans] > siz[i]) ans = i;
            }
            printf("%d
    ", siz[ans]);
            for(int i = 1;i <= n; ++i)
            {
                if(answer[i] == ans) printf("%d ",i);
            }
            printf("
    ");
        }
    }T;
    int main()
    {
        scanf("%d%d%d",&n,&m,&h);
        for(int i = 1;i <= n; ++i) scanf("%d",&C[i]);
        while(m--){
            int a,b;
            scanf("%d%d",&a,&b);
            if(((C[a] + 1) % h) == C[b]) T.add_edge(a, b);
            if(((C[b] + 1) % h) == C[a]) T.add_edge(b, a);
        }
        T.solve();
        return 0;
    }
    
  • 相关阅读:
    SVN Windows环境搭建,简洁演示
    SVN-linux配置
    链接文本在a标签内标签里也可以用driver.find_element_by_link_text
    selenium python自动化简明演示
    关键字中mysql数据库查询条件带中文无结果解决办法
    python 最短路径
    python 难度分割
    c语言实现一个高铁乘客管理系统
    Linux(Ubuntu)系统安装图文教程
    字符串排序
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845102.html
Copyright © 2011-2022 走看看