受牛仰慕的牛

Description

每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

Input

第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)

Output

一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1【数据范围】
10%的数据N<=20, M<=50
30%的数据N<=1000,M<=20000
70%的数据N<=5000,M<=50000
100%的数据N<=10000,M<=50000

  1.找到所有强连通块
    2.计算所有联通块的出度
    3.如果有一个联通块出度为零,说明为最受欢迎的牛群
    4.如果存在两个联通块出度为零,说明不存在最受欢迎的牛

  1 #include <cstdlib>
  2 #include <iostream>
  3 #include <fstream>
  4 #include <cstring>
  5 /* run this program using the console pauser or add your own getch,  or input loop */
  6
  7 using namespace std;
  8
  9 ifstream fin("popular.in");
 10 ofstream fout("popular.out");
 11
 12 int cows=0,roads=0;
 13
 14 int head[10002]={0},cnt_lian=0;
 15 struct lian{
 16     int to;
 17     int next;
 18 };
 19 lian liansi[50002]={0};//链式前向星
 20
 21 int top=0;
 22 int stack[10002]={0};
 23 bool instack[10002]={0};//是否在栈里面
 24
 25 int cnt_dfn=0;//记录步数
 26 int dfn[10002]={0};
 27 int low[10002]={0};
 28
 29
 30
 31 int cnt_scc_node=0;//记录有几个联通块
 32 int scc_node[10002]={0};//记录每个联通块里面有几个奶牛
 33 int scc_belong[10002]={0};//记录每个奶牛属于几号联通块
 34
 35 bool cnt_chudu[10002]={0};//记录每个联通块是否有出度
 36
 37 void cun_lian(int a,int b);//存 链式前向星
 38 void scc_meijv( );//枚举没有走到的点
 39 void scc(int hao);//tarjan算法算联通块
 40
 41 void cun_lian(int a,int b){
 42      liansi[++cnt_lian].next=head[a];
 43      liansi[cnt_lian].to=b;
 44      head[a]=cnt_lian;
 45      return;
 46 }
 47
 48 void scc_meijv(){
 49      for(int x=1;x<=cows;x++){
 50          if(dfn[x]==0)scc(x);//如果有一个点没走到,就去枚举
 51      }
 52      return;
 53 }
 54
 55 void scc(int hao){
 56      cnt_dfn++;
 57      dfn[hao]=cnt_dfn;
 58      low[hao]=cnt_dfn;//low默认为此时走到的步数
 59
 60      stack[++top]=hao;
 61      instack[hao]=true;//入栈
 62
 63      for(int x=head[hao];x!=-1;x=liansi[x].next){
 64          int dao=liansi[x].to;
 65          if(dfn[dao]==0){//如果没有算过
 66                scc(dao);//就去计算
 67               low[hao]=min(low[hao],low[dao]);
 68         }
 69         else if (instack[dao]){//如果在栈中
 70            low[hao] = min(low[hao], dfn[dao]);
 71         }
 72      }
 73
 74      if(dfn[hao]==low[hao]){//表示出现了一个联通块
 75         cnt_scc_node++;//联通块个数加一
 76         int ding=0;
 77         do{
 78               ding=stack[top--];
 79               scc_belong[ding]=cnt_scc_node;
 80            scc_node[cnt_scc_node]++;
 81               instack[ding]=false;//一个一个出栈,并作好记录
 82            }while(ding!=hao);
 83     }
 84
 85     return;
 86 }
 87
 88 int main(int argc, char *argv[]) {
 89      fin>>cows>>roads;
 90
 91      memset(head,-1,sizeof(head));
 92      for(int x=1;x<=roads;x++){
 93          int a,b;
 94          fin>>a>>b;
 95          cun_lian(a,b);
 96     }
 97
 98
 99      scc_meijv();
100
101      for(int x=1;x<=cows;x++){
102          int size_x=scc_belong[x];
103          for(int y=head[x];y!=-1;y=liansi[y].next){//搜索每一头奶牛的出度
104             if(cnt_chudu[size_x]==true)break;//如果这个奶牛所在的联通块已经有了出度,便可以不用计算.
105                int dao=liansi[y].to;
106             int size_y=scc_belong[dao];
107                if(size_x!=size_y){//如果枚举的奶牛的出度所连的不是同一个联通块
108                  cnt_chudu[size_x]=true; break;//表示这头奶油所在的联通块有了出度
109               }
110          }
111      }
112
113     int cnt_pop_scc=0;//记录出度为零的联通块
114     int cnt_pop_cow=0;//记录最受欢迎的牛的个数
115     for(int x=1;x<=cnt_scc_node;x++){//枚举每个联通块
116           if(cnt_chudu[x]==false){//如果有一个联通块出度为零
117              cnt_pop_scc++;//那么出度为零的联通块的个数加一
118              cnt_pop_cow+=scc_node[x];//加上里面所以奶牛
119            if(cnt_pop_scc>1){//当出度为零的联通块的个数大于一说明不存在最受欢迎的牛奶联通块
120                cnt_pop_cow=0; break;//最受欢迎的牛的个数为零
121              }
122          }
123     }
124
125
126      cout<<cnt_pop_cow;
127      fout<<cnt_pop_cow;
128
129     return 0;
130 }
131
132 
时间: 2024-10-23 21:22:47

受牛仰慕的牛的相关文章

【POJ2186】受牛仰慕的牛

受牛仰慕的牛(popular cows)  每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有N(1<=N<=10,000)头牛的牛群中,给你M(1<=M<=50,000)个二元组(A,B),表示A认为B是受欢迎的.既然受欢迎是可传递的,那么如果A认为B受欢迎,B又认为C受欢迎,则A也会认为C是受欢迎的,哪怕这不是十分明确的规定.你的任务是计算被所有其它的牛都喜欢的牛的个数. 这道题直接考虑模拟是不行的,要考虑抽象模型.将仰慕关系建立成一个有向图,然后计算出强连通分量,缩点

poj 2481 Cows(输出每头牛有几头牛比其强壮,明牛i比牛j强壮:Si &lt;=Sjand Ej &lt;= Ei and Ei - Si &gt; Ej - Sj)

Cows Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 15834 Accepted: 5271 Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his fi

【牛客】牛客练习赛16(未完)

A  字典序最大的子序列 题意:给定字符串s,s只包含小写字母,请求出字典序最大的子序列.(看例子就能看明白) 思路:从这个字符串a后面开始比较,先把最后一个字母存进s,然后那那s中最新的一个元素跟a中上一个进行比较,如果a不比s小,则存入s,并把这个看做新哒~ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; char s[100007]; int ma

POJ 2186 Popular Cows(Targin缩点)

传送门 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31808   Accepted: 12921 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <=

连通图练习总结

连通图是图论基于联通的一个概念,在ACM中针对图论的考察一部分是也是基于连通图.针对这类问题的解题基本思路就是先求出对应的连通分量(有向图的强连通,无向图的双连通)对图进行简化,然后再结合其他算法计算. 1. POJ 3180 The Cow Prom 这个题如果能理解题目的话,怎么做就很明显了,能形成一个可以转圈的小群,就相当于一个强连通分量,需要注意的就是这个小群不可以只有一头牛. #include <set> #include <map> #include <list&

bzoj1051【HAOI2006】受欢迎的牛

1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3491  Solved: 1837 [Submit][Status][Discuss] Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. I

HAOI2006 受欢迎的牛

HAOI2006 ]受欢迎的牛 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛 A 认为牛 B受欢迎.这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Input 第1行两个整数N,M: 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的

[BZOJ1051] [HAOI2006] 受欢迎的牛 (强联通分量)

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可 能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的. Sample Input 3

【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的. Sample Input 3 3