每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。
标签:
tarjan缩点。判断是否只有一个没有出边。是则输出该点点数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define op() clr(head,0);pt=edges;
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
int x=0;char c=getchar();bool f=true;
while(!isdigit(c)){
if(c==‘-‘) f=false;c=getchar();
}
while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
return f?x:-x;
}
const int nmax=10005;
const int maxn=50005;
const int inf=0x7f7f7f7f;
struct edge{
int to;edge *next;
};
edge edges[maxn],*pt,*head[nmax];
int pre[nmax],sccno[nmax],out[nmax],scc_cnt,dfs_clock;
stack<int>s;
void adde(int u,int v){
pt->to=v;pt->next=head[u];head[u]=pt++;
}
int dfs(int x){
int lowu=pre[x]=++dfs_clock;s.push(x);
qwq(x) {
int to=o->to;
if(!pre[to]) lowu=min(lowu,dfs(to));
else if(!sccno[to]) lowu=min(lowu,pre[to]);
}
if(lowu==pre[x]){
scc_cnt++;
while(1){
int X=s.top();s.pop();
sccno[X]=scc_cnt;
if(x==X) break;
}
}
return lowu;
}
void init(){
op();clr(out,false);clr(pre,0);clr(sccno,0);dfs_clock=scc_cnt=0;
}
int main(){
init();
int n=read(),m=read(),u,v,ans=0,cur,cnt=0;
rep(i,m) u=read(),v=read(),adde(u,v);
rep(i,n) if(!pre[i]) dfs(i);
rep(i,n) qwq(i) if(sccno[i]!=sccno[o->to]) out[sccno[i]]=true;
rep(i,scc_cnt) if(!out[i]) cnt++,cur=i;
if(cnt==1) rep(i,n) if(sccno[i]==cur) ans++;
printf("%d\n",ans);
}
一个数,即有多少头牛被所有的牛认为是受欢迎的。
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5672879.html