洛谷 P2341 [HAOI2006]受欢迎的牛

来源:互联网 发布:maven java目录下的xml 编辑:程序博客网 时间:2024/06/18 07:36

题目链接https://www.luogu.org/problem/show?pid=2341

题目描述

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

算出有多少头奶牛可以当明星。

输入输出格式

输入格式:
 第一行:两个用空格分开的整数:N和M

 第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

输出格式:
 第一行:单独一个整数,表示明星奶牛的数量

输入输出样例

输入样例#1:
3 3
1 2
2 1
2 3
输出样例#1:
1
说明

只有 3 号奶牛可以做明星

【数据范围】

10%的数据N<=20, M<=50

30%的数据N<=1000,M<=20000

70%的数据N<=5000,M<=50000

100%的数据N<=10000,M<=50000

#include <cstdio>#include <iostream>#include <cstring>#include <vector>#define N 50005*2#include <set>using namespace std;int n,m;int dfn[N];int tim=0;int topp=0;int low[N];int bel[N];int cnt;bool v[N];int stack[N];int out[N];int in[N];int size[N];vector <int> g[N];vector <int> outt[N];set <int> to[N];void tarjan(int x){    dfn[x]=low[x]=++tim;    stack[++topp]=x;    v[x]=true;    for(int i=0;i<g[x].size();i++){        if(!dfn[g[x][i]]){            tarjan(g[x][i]);            low[x]=min(low[x],low[g[x][i]]);        }        else if(v[g[x][i]]) low[x]=min(low[x],dfn[g[x][i]]);    }    if(low[x]==dfn[x]){        int vv;        cnt++;        do{            vv=stack[topp--];            bel[vv]=cnt;            size[cnt]++;            v[vv]=false;        }while(vv!=x);    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        int a,b;        scanf("%d%d",&a,&b);        g[a].push_back(b);    }    for(int i=1;i<=n;i++){        if(!dfn[i]) tarjan(i);    }    for(int i=1;i<=n;i++)        for(int j=0;j<g[i].size();j++){            int dng=g[i][j];            if(bel[i]!=bel[dng])            {                to[bel[i]].insert(bel[j]);//防重边             }        }        int ans=0;        int pos;    for(int i=1;i<=cnt;i++)        if(to[i].empty())            ans++, pos=i;    if(ans==1) printf("%d",size[pos]);    else printf("0");    return 0;}

tarjan缩点

原创粉丝点击