洛谷 P2341 [HAOI2006]受歡迎的牛|【模板】強連通分量

思路:求出度爲0的點的聯通數量,如果出度爲0的點有一個以上,則爲0

/*
洛谷 P2341
每頭奶牛都夢想成爲牛棚裏的明星。被所有奶牛喜歡的奶牛就是一頭明星奶牛。所有奶
牛都是自戀狂,每頭奶牛總是喜歡自己的。奶牛之間的“喜歡”是可以傳遞的——如果A喜
歡B,B喜歡C,那麼A也喜歡C。牛欄裏共有N 頭奶牛,給定一些奶牛之間的愛慕關係,請你
算出有多少頭奶牛可以當明星。
第一行:兩個用空格分開的整數:N和M
第二行到第M + 1行:每行兩個用空格分開的整數:A和B,表示A喜歡B
第一行:單獨一個整數,表示明星奶牛的數量

3 3
1 2
2 1
2 3
ans:
1
*/
#include<bits/stdc++.h>
#define M 10010
using namespace std;
int n,m,tot,indox;
int DNF[M],LOW[M],book[M],rin[M],sum[M];
vector<int>V[M];
stack<int> q;
void tarjan(int u)
{

    DNF[u]=LOW[u]=++tot;
    book[u]=1;
    q.push(u);
    for(auto v:V[u])
    {
        if(DNF[v]==-1)
        {
            tarjan(v);
            LOW[u]=min(LOW[u],LOW[v]);
        }
        else if(book[v])
            LOW[u]=min(LOW[u],DNF[v]);
    }
    if(DNF[u]==LOW[u])
    {
        ++indox;
        int tem;
        do
        {
            tem=q.top();
            q.pop();
            book[tem]=0;
            rin[tem]=indox;
            sum[indox]++;
        }while(tem!=u);
    }
}
void init()
{
    for(int i=1;i<=n;i++)
        V[i].clear();
    memset(DNF,-1,sizeof(DNF));
}
int out[M];//記錄出度
void solve()
{
    for(int u=1;u<=n;u++)
    {
        for(auto v:V[u])
        {
            if(rin[u]==rin[v]) continue;
            out[rin[u]]++;
        }
    }
    int ans=0;
    for(int i=1;i<=indox;i++)
    {
        if(out[i]==0)
        {
            ans=ans==0?sum[i]:-1;
        }
    }
    printf("%d\n",ans==-1?0:ans);
}
int main()
{
    int x,y;
    init();
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        V[x].push_back(y);
    }
    for(int i=1;i<=n;i++)
    {
        if(DNF[i]==-1)
        {
            tarjan(i);
        }
    }
    solve();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章