Luo Gu P2341 - Popular cow

Title Description

P2341 [USACO03FALL] [HAOI2006] popular bovine G

solution:

First of all, what is clear cow star: popular cattle may only be the only out-degree view of all the cows in the strongly connected component 0 in.

why?

Strongly connected components, all nodes can reach each other, which means that all cows in a strong link components each like. The degree is not 0, then the strongly connected components of the cows are not necessarily satisfied liked all cows conditions (of course, a node can be considered one strong link component, if the node a is 0, is also a star cows)

If there is more than two out of two and is strongly connected component of 0, it is two independent, in other words when all the cows is not like any of the first component a second component of the cow, can be pushed empathy the second component, so these are independent of the strongly connected component is not a star cows cow

#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;
}
Published 152 original articles · won praise 22 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_38204302/article/details/105287772