题意:有 n 头牛,以及一些喜欢关系,牛 A 喜欢牛 B,这种关系可以传递,问有多少头牛被牧场上所有牛喜欢。
首先强连通,因为在同一个强连通分量中牛是等价的,然后对于一个有向无环图看是否只有一个强连通分量出度为 0 ,如果是,则这个强连通分量中的点都是答案,否则为 0。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stack> 4 #include<queue> 5 using namespace std; 6 7 const int maxn=10005; 8 const int maxm=50005; 9 10 int head[maxn],point[maxm],nxt[maxm],size; 11 int n,t,scccnt; 12 int stx[maxn],low[maxn],scc[maxn],od[maxn]; 13 stack<int>S; 14 15 void init(){ 16 memset(head,-1,sizeof(head)); 17 size=0; 18 memset(od,0,sizeof(od)); 19 } 20 21 void add(int a,int b){ 22 point[size]=b; 23 nxt[size]=head[a]; 24 head[a]=size++; 25 } 26 27 void dfs(int s){ 28 stx[s]=low[s]=++t; 29 S.push(s); 30 for(int i=head[s];~i;i=nxt[i]){ 31 int j=point[i]; 32 if(!stx[j]){ 33 dfs(j); 34 low[s]=min(low[s],low[j]); 35 } 36 else if(!scc[j]){ 37 low[s]=min(low[s],stx[j]); 38 } 39 } 40 if(low[s]==stx[s]){ 41 scccnt++; 42 while(1){ 43 int u=S.top();S.pop(); 44 scc[u]=scccnt; 45 if(s==u)break; 46 } 47 } 48 } 49 50 void setscc(){ 51 memset(stx,0,sizeof(stx)); 52 memset(scc,0,sizeof(scc)); 53 t=scccnt=0; 54 for(int i=1;i<=n;++i)if(!stx[i])dfs(i); 55 for(int i=1;i<=n;++i){ 56 for(int j=head[i];~j;j=nxt[j]){ 57 int k=point[j]; 58 if(scc[i]!=scc[k]){ 59 od[scc[i]]++; 60 } 61 } 62 } 63 } 64 65 int main(){ 66 int m; 67 while(scanf("%d%d",&n,&m)!=EOF){ 68 init(); 69 while(m--){ 70 int a,b; 71 scanf("%d%d",&a,&b); 72 add(a,b); 73 } 74 setscc(); 75 int ans=0; 76 if(scccnt==1)printf("%d\n",n); 77 else{ 78 for(int i=1;i<=scccnt;++i)if(!od[i])ans++; 79 if(ans!=1){ 80 printf("0\n"); 81 } 82 else{ 83 ans=0; 84 for(int i=1;i<=n;++i){ 85 if(!od[scc[i]])ans++; 86 } 87 printf("%d\n",ans); 88 } 89 } 90 } 91 return 0; 92 }
时间: 2024-10-13 20:36:32