CF949C Data Center Maintenance Tarjan找强连通分量

Posted brunch

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF949C Data Center Maintenance Tarjan找强连通分量相关的知识,希望对你有一定的参考价值。

题意

  • 给你(n)个点,每个点有一个权值(a_x),有(m)个限制条件形如(a_x≠a_y),现在要求你选出(k(k>0))个点使其权值在模(h)意义下加(1),问最少选多少个点能让限制条件继续满足。

(Tarjan)求强连通分量模板题

发现对于每个限制条件,如果(a_x+1=a_y(mod h))

那么可以给(y)(x)连一条有向边

那么最后缩点后找到入度为(0)的最小(scc)大小即可

Codes

#include <cstdio>
#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int colors, n, m, h, a[N], be[N], size[N], de[N];

namespace Tarjan {
    int from[N << 1], to[N << 1], nxt[N << 1], head[N], e;
    int ins[N], Sta[N], low[N], dfn[N], dfn_cnt, top;

    inline void add(int x, int y) {
        to[++ e] = y; nxt[e] = head[x]; head[x] = e;
    }

    inline void dfs(int x) {
        low[x] = dfn[x] = ++ dfn_cnt, ins[Sta[++ top] = x] = 1;
        for (int i = head[x]; i; i = nxt[i]) {
            if (!dfn[to[i]]) {
                dfs(to[i]);
                low[x] = min(low[to[i]], low[x]);
            }
            else if (ins[to[i]]) 
                low[x] = min(dfn[to[i]], low[x]);
        }
        if (low[x] == dfn[x]) {
            ++ colors; 
            do {
                ++ size[be[Sta[top]] = colors]; 
                ins[Sta[top]] = 0;
            }while (Sta[top --] ^ x);
        }
    }

    inline void Get_Ans() {
        for (int x = 1; x <= n; ++ x) 
            for (int i = head[x]; i; i = nxt[i])
                if (be[x] ^ be[to[i]])
                    ++ de[be[to[i]]];
        int ans = 1e9, id;
        for (int i = 1; i <= colors; ++ i) 
            if (!de[i] && size[i] < ans)
                ans = size[i], id = i;
        printf("%d
", ans);
        for (int i = 1; i <= n; ++ i) 
            if (be[i] == id) 
                printf("%d ", i);
    }
}

int main() {
#ifdef ylsakioi
    freopen("cf949c.in", "r", stdin);
    freopen("cf949c.out", "w", stdout);
#endif

    scanf("%d%d%d", &n, &m, &h);
    for (int i = 1; i <= n; ++ i) 
        scanf("%d", &a[i]);
    for (int x, y, i = 1; i <= m; ++ i) {
        scanf("%d%d", &x, &y);
        if ((a[x] + 1) % h == a[y]) Tarjan::add(y, x);
        if ((a[y] + 1) % h == a[x]) Tarjan::add(x, y);
    }

    for (int i = 1; i <= n; ++ i) 
        if (!Tarjan::dfn[i])
            Tarjan::dfs(i);
    Tarjan::Get_Ans();

    return 0;
}

以上是关于CF949C Data Center Maintenance Tarjan找强连通分量的主要内容,如果未能解决你的问题,请参考以下文章

CF949C Data Center Maintenance(建图+强联通分量)

CF949C Data Center Maintenance Tarjan找强连通分量

codeforces 949C - Data Center Maintenancetarjan

cf950e Data Center Maintenance

CF949 C Data Center Maintenance——边双连通分量

“MySql.Data.CF”和“MySql.Data”中都存在“MySqlConnection”类型