1045: 明星奶牛
时间限制: 1 Sec 内存限制: 128 MB提交: 82 解决: 43
[ 提交][ 状态][ 讨论版]
题目描述
每个奶牛都想成为明星奶牛,总共有N只奶牛,和M对关系(A, B),表示A认为B可以成为明星。这种关系可以传递的,比如A认为B可以成为明星,B认为C可以成为明星,那么暗指A也认为C可以成为明显。事实上,只有被其他所有奶牛认可,才算明星奶牛,那么问有多少只奶牛真正是明星奶牛?
输入
输入
n
和
m
然后
m
行每行输入
A B
,
表示
A
认可
B
输出
输出明星奶牛数量
样例输入
3 3
1 2
2 1
2 3
样例输出
1
提示
【样例说明】
1和2相互认可,2认可3,暗指1也认可3,所以3被1,2都认可
所以只有3才是明星奶牛
【数据规模和约定】
1<=n<=10000
1<=m<=50000
来源
代码如下:
#include<bits/stdc++.h>
#define N 10005
#define M 100005
using namespace std;
int tot,Head[N],Next[M],vet[M];
void add(int x,int y){
tot++;
vet[tot]=y;
Next[tot]=Head[x];
Head[x]=tot;
}
int ans,n,m,scc_cnt,nscc[N],out[N];
int dfs_clock,low[N],dfn[N],sccno[N];
stack <int> s;
void dfs(int u){
dfn[u]=low[u]=++dfs_clock;
s.push(u);
for(int i=Head[u];i;i=Next[i]){
int v=vet[i];
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else
if(!sccno[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
scc_cnt++;
for(;;){
int v=s.top();
s.pop();
sccno[v]=scc_cnt;
nscc[scc_cnt]++;
if(v==u)break;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])dfs(i);
for(int u=1;u<=n;u++)
for(int i=Head[u];i;i=Next[i]){
int v=vet[i];
if(sccno[u]!=sccno[v])out[sccno[u]]++;
}
int flag=0,t;
for(int i=1;i<=scc_cnt;i++)
if(!out[i]){
flag++;
t=i;
}
if(flag==1) printf("%d\n",nscc[t]);
else printf("0\n");
return 0;
}