Cow Ski Area
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2191 | Accepted: 627 |
Description
Input
Output
Sample Input
9 3
1 1 1 2 2 2 1 1 1
1 2 1 2 3 2 1 2 1
1 1 1 2 2 2 1 1 1
Sample Output
3
Hint
Source
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define clear( a , x ) memset ( a , x , sizeof a ) const int MAXN = 260000 ; const int MAXE = 1200000 ; const int MAXG = 505 ; struct Edge { int v , n ; Edge ( int var = 0 , int next = 0 ) : v(var) , n(next) {} } ; struct SCC { Edge edge[MAXE] ; int adj[MAXN] , cntE ; int Dfn[MAXN] , Low[MAXN] , dfs_clock ; int scc[MAXN] , scc_cnt ; int S[MAXN] , top ; bool ins[MAXN] ; bool ou[MAXN] , in[MAXN] ; void init () { top = 0 ; cntE = 0 ; scc_cnt = 0 ; dfs_clock = 0 ; clear ( ou , 0 ) ; clear ( in , 0 ) ; clear ( ins , 0 ) ; clear ( Dfn , 0 ) ; clear ( adj , -1 ) ; } void addedge ( int u , int v ) { edge[cntE] = Edge ( v , adj[u] ) ; adj[u] = cntE ++ ; } void Tarjan ( int u ) { Dfn[u] = Low[u] = ++ dfs_clock ; S[top ++] = u ; ins[u] = 1 ; for ( int i = adj[u] ; ~i ; i = edge[i].n ) { int v = edge[i].v ; if ( !Dfn[v] ) { Tarjan ( v ) ; Low[u] = min ( Low[u] , Low[v] ) ; } else if ( ins[v] ) Low[u] = min ( Low[u] , Dfn[v] ) ; } if ( Low[u] == Dfn[u] ) { ++ scc_cnt ; while ( 1 ) { int v = S[-- top] ; ins[v] = 0 ; scc[v] = scc_cnt ; if ( v == u ) break ; } } } void find_scc ( int n ) { REP ( i , n ) if ( !Dfn[i] ) Tarjan ( i ) ; } void solve ( int n ) { REP ( u , n ) for ( int i = adj[u] ; ~i ; i = edge[i].n ) { int v = edge[i].v ; if ( scc[u] != scc[v] ) { ou[scc[u]] = 1 ; in[scc[v]] = 1 ; } } int cnt_in = 0 , cnt_ou = 0 ; REPF ( i , 1 , scc_cnt ) { if ( !ou[i] ) ++ cnt_ou ; if ( !in[i] ) ++ cnt_in ; } printf ( "%d\n" , max ( cnt_in , cnt_ou ) ) ; } } ; SCC C ; int G[MAXG][MAXG] ; void work () { int n , m ; int u , v ; while ( ~scanf ( "%d%d" , &m , &n ) ) { C.init () ; REP ( i , n ) REP ( j , m ) scanf ( "%d" , &G[i][j] ) ; REP ( i , n ) REP ( j , m ) { int ij = i * m + j ; if ( i > 0 && G[i][j] >= G[i - 1][j] ) C.addedge ( ij , ij - m ) ; if ( j > 0 && G[i][j] >= G[i][j - 1] ) C.addedge ( ij , ij - 1 ) ; if ( i < n - 1 && G[i][j] >= G[i + 1][j] ) C.addedge ( ij , ij + m ) ; if ( j < m - 1 && G[i][j] >= G[i][j + 1] ) C.addedge ( ij , ij + 1 ) ; } C.find_scc ( n * m ) ; if ( C.scc_cnt == 1 ) { printf ( "0\n" ) ; continue ; } C.solve ( n * m ) ; } } int main () { work () ; return 0 ; }