Popular Cows
Time Limit:2000 MS |
|
Memory Limit:65536 K |
Total Submissions:19089 |
|
Accepted:7678 |
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 <= M <= 50,000) ordered pairs of the form (, b) that tell you that cow A thinks that cow B is popular. since popularity is transitive, If A thinks B is popular and B thinks C is popular, then A will also think that C is Popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.Input * Line 1: Two space-separated integers, N and M* Lines 2 .. 1 + M: Two space-separated numbers A and B, meaning that A thinks B is popular. Output * Line 1: A single integer that is the number of cows who are considered popular by every other cow.Sample Input 3 31 22 12 3 Sample Output 1 Hint Cow 3 is the only cow of high popularity.Source USACO 2003 Fall |
Analysis: At the beginning, I understood the incorrect question and thought it was the best way to find out the most popular ox. It is to find the number of ox X that every ox thinks. That is, finding a point with zero degree of output in a DAG. If there are two points with zero degree of output, it is impossible to have such a cow.
Method: 1. Create a strongly connected branch and convert the graph into a DAG.
2. Find the connected branch or point with zero degree in the DAG.
Code:
# Include <cstdio> # include <cstring> # include <vector> using namespace std; const int maxn = 10010; vector <int> G [maxn], Gt [maxn]; int ord [maxn]; int vis [maxn]; int out [maxn]; int ss [maxn]; int ans [maxn]; int cnt; int t; int n, m; void dfs_1 (int u) {vis [u] = 1; for (int I = 0; I <G [u]. size (); I ++) {int v = G [u] [I]; if (! Vis [v]) dfs_1 (v);} ord [t ++] = u;} void dfs_2 (int u) {vis [u] = 1; ss [u] = cnt; for (int I = 0; I <Gt [u]. size (); I ++) {int v = Gt [u] [I]; if (! Vis [v]) {ans [cnt] ++; dfs_2 (v) ;}} void kosaraju () {int flag =-1; t = 1; cnt = 1; for (int I = 1; I <= n; I ++) ans [I] = 1; memset (out, 0, sizeof (out); memset (vis, 0, sizeof (vis); for (int I = 1; I <= n; I ++) if (! Vis [I]) dfs_1 (I); memset (vis, 0, sizeof (vis); for (int I = t-1; I> = 1; I --) {int v = ord [I]; if (! Vis [v]) {dfs_2 (v); cnt ++ ;}// construct a DAG for (int I = 1; I <= n; I ++) {for (int j = 0; j <G [I]. size (); j ++) {if (ss [I] = ss [G [I] [j]) continue; out [ss [I] ++ ;}// find the point with zero degree or connected branch for (int I = 1; I <cnt; I ++) {if (! Out [I] & flag =-1) flag = ans [I]; else if (! Out [I] & flag! =-1) {flag = 0; break;} printf ("% d \ n", flag);} int main () {while (scanf ("% d", & n, & m )! = EOF) {for (int I = 1; I <= m; I ++) {int u, v; scanf ("% d", & u, & v); G [u]. push_back (v); Gt [v]. push_back (u);} kosaraju ();} return 0 ;}