Luo Gu P2341 - vaca populares

título Descripción

P2341 [USACO03FALL] [HAOI2006] bovina populares G

solución:

En primer lugar, ¿cuál es la estrella de vaca claro: el ganado turístico, solo pueden ser vistas sólo por el grado de todas las vacas en el componente fuertemente conexa 0 en.

¿Por qué?

Totalmente de componentes conectados, todos los nodos pueden alcanzar entre sí, lo que significa que todas las vacas de una fuerte Componentes del circuito cada uno como. El grado no es 0, entonces los componentes fuertemente conectados de las vacas no están necesariamente satisfechas le gusta todas las condiciones de vacas (por supuesto, un nodo puede ser considerada una fuerte componente de enlace, si el nodo a es 0, es también una estrella vacas)

Si hay más de dos de cada dos y es fuerte componente conectado de 0, es dos independientes, es decir, cuando todas las vacas no es como cualquiera de la primera componente de un segundo componente de la vaca, la empatía puede ser empujado el segundo componente, por lo que estos son independientes de la componente fuertemente conectado no es una vaca vacas estrella

#include <bits/stdc++.h>
using namespace std;

int n, m, a, b, t, cnt, cont, ans;
int v[100010], nex[100010]
int fst[10010], fn[10010], low[10010], scc[10010], ssize[10010], out[10010];
bool f[10010];
stack<int> s;

void tarjan(int k){
    low[k] = dfn[k] = ++t;
    f[k] = true;
    s.push(k);
    for(int i=fst[k];i!=-1;i=nex[i]){
        if(!dfn[v[i]]){
            tarjan(v[i]);
            low[k] = min(low[k],low[v[i]]);
        }
        else{
            if(f[v[i]])
                low[k] = min(low[k], dfn[v[i]]);
        }

    }
    if(low[k]==dfn[k]){
        f[k] = false;
        scc[k] = ++cnt; // cnt记录强连通分量个数,ssc表示k在第cnt个强联通分中
        ssize[cnt] = 1; // ssize记录第cnt个强联通分量的成员数
        while(s.top()!=k){
            scc[s.top()] = cnt;
            f[s.top()] = false;
            ssize[cnt]++;
            s.pop();
        }
        s.pop();
    }
    return;
}

int main()
{
    cin >> n >> m;
    memset(fst, -1, sizeof(fst));
    memset(low, 0x7f, sizeof(low));
    for(int i=1;i<=m;i++){
        scanf("%d%d", &a, &b);
        nex[i] = fst[a];
        v[i]= b;
        fst[a] = i;
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]){
            t = 0;
            tarjan(i);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=fst[i];j!=-1;j=nex[j]){
            if(scc[i]!=scc[v[j]]) // 如果i和其邻接点不再一个连通分量,则该连通分量有一个出度
                out[scc[i]]++;
        }
    }
    // 记录出度为0的强联通分量
    for(int i=1;i<=cnt;i++){
        if(out[i]==0){
            cont++;
            ans += ssize[i];
        }
    }
    if(cont==1)
        cout << ans;
    else
        cout << 0;
    return 0;
}
Publicados 152 artículos originales · ganado elogios 22 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/qq_38204302/article/details/105287772
Recomendado
Clasificación