思路:强连通缩点,每个点就是一个点,能走的建边,缩点后找入度出度为0的个数的最大值就是答案,注意一开始就强连通了答案应该是0
#include<cstdio> #include<cstring> #include<map> #include<vector> #include<cmath> #include<cstdlib> #include<queue> #include <iomanip> #include<iostream> #include<algorithm> using namespace std ; const int N= 300000 ; const int M= 2222222 ; const int dx[] = {-1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; struct node { int u , v , next ; }edge[M] ; int head[N],vist[N],low[N],dfn[N],belong[N],stack[N],g[505][505] ,out[N],in[N]; int top , sum , cnt , dep , n,m ; int cheak(int i , int j) { if( i >= 0 && i < n && j >= 0 && j<m) return 1; return 0; } void add(int u ,int v) { edge[top].u=u; edge[top].v=v; edge[top].next=head[u]; head[u]=top++; } void tarjan(int u ) { low[u]=dfn[u]=++dep; stack[cnt++]=u; vist[u]=1; for(int i = head[u] ; i!=-1 ; i=edge[i].next) { int v= edge[i].v ; if(!dfn[v]) { tarjan(v) ; low[u] = min( low[u] , low[v] ) ; }else if(vist[v]) low[u] = min( low[u] , dfn[v] ); } if(low[u] == dfn[u]) { int x; sum++ ; do { x=stack[--cnt] ; vist[x] = 0 ; belong[x]=sum; }while(x!=u) ; } } int main() { int w =0; while(~scanf("%d%d",&m,&n)) { top =0 ; sum = 0 ;dep = 0 ;cnt = 0 ; memset(head,-1,sizeof(head)) ; memset(low,0,sizeof(low)) ; memset(dfn,0,sizeof(dfn)) ; memset(vist,0,sizeof(vist)) ; memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < m ; j++) scanf("%d",&g[i][j]) ; for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < m ; j++) for(int k = 0 ; k < 4 ; k++) { int xx = i + dx[k] ; int yy = j + dy[k] ; int u = i*m+j ,v=xx*m+yy ; if(cheak(xx,yy)) { if(g[i][j] >= g[xx][yy]) { add(u,v);w++; } if(g[i][j] <= g[xx][yy]) { add(v,u);w++; } } } // printf("%d\n",w); for(int i = 0 ; i < n*m ; i++) if(!dfn[i]) tarjan(i) ; // printf("*%d* ",sum); for(int i = 0 ; i < n*m ; i++) for(int j= head[i] ; j!=-1; j=edge[j].next) { int v = edge[j].v ; if(belong[i] != belong[v]) { in[belong[v]]++ ; out[belong[i]]++; } } if(sum <= 1 ) //刚开始强联通的 printf("0\n") ; else { int a=0,b=0; for(int i = 1 ; i <= sum ; i++) { if(out[i] == 0) a++ ; if(in[i] == 0) b++ ; } printf("%d\n",max(a,b)) ; } } return 0; }