P2341 [USACO03FALL / HAOI2006] 受欢迎的牛 G

 

>>> de[]->big lian  

>>>co[] -> point belong

>>>只能统计 极值  cd rd ==0

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=5e4+10;

int n,m; 
int head[maxn],to[maxn],nxt[maxn],tot;
int dfn[maxn],low[maxn],dfs_t,st[maxn],top=0,co[maxn],col=0,s[maxn];
int de[maxn],cd[maxn];

void add(int a,int b){
    to[++tot]=b; nxt[tot]=head[a]; head[a]=tot;
}

void tarjan(int u)
{
    low[u]=dfn[u]=++dfs_t;
    st[++top]=u;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(dfn[v]==0)
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(co[v]==0) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        co[u]=++col;
        s[col]++;
        while(st[top]!=u)
        {
            co[st[top--]]=col;
            s[col]++;
        }
        top--;
    }
}
int main()  
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v; cin>>u>>v;
        //add(v,u);// in easy  out hard
        add(u,v);
    }
    for(int i=1;i<=n;i++) if(dfn[i]==0) tarjan(i);
    
    for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=nxt[j])
            {
                if(co[i]!=co[to[j]]){
                    de[co[to[j]]]++;//co[] -> point i belong to 强连通分量 
                    cd[co[i]]++;
                }
            }

    int tmp=0,ans=0;
    for(int i=1;i<=col;i++) 
    {
        /*if(de[i]==0)//de[] 强连通分量  
        {
            tmp++;
            ans=s[i];
        }*/
        if(cd[i]==0)
        {
            tmp++;
            ans=s[i];
        }
        
    }
    if(tmp==1){ cout<<ans<<'\n';}
    else cout<<"0"<<'\n';
    
    return 0;
}
View Code

 

 

 
 
 
posted @ 2023-08-07 17:19  JMXZ  阅读(11)  评论(0)    收藏  举报