POJ 2375
BFS+强连通。输出max(缩点后出度为0的点数,缩点后入度为0的点数)。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cctype> 5 #include <algorithm> 6 #define LL unsigned __int64 7 using namespace std; 8 9 const int N= 250050; 10 11 struct Edge{ 12 int u,v; 13 int next; 14 }edge[N*4]; 15 int tot,index; 16 int head[N],dfn[N],low[N],stack[N],st; 17 int outdegree[N],indegree[N]; 18 int belong[N],beg; 19 bool instack[N]; 20 int map[510][510]; 21 22 int dir[4][2]={ 23 {0,1}, 24 {0,-1}, 25 {1,0}, 26 {-1,0} 27 }; 28 29 void addedge(int u,int v){ 30 edge[tot].u=u; 31 edge[tot].v=v; 32 edge[tot].next=head[u]; 33 head[u]=tot++; 34 } 35 36 void Tarjan(int u) { 37 dfn[u]=low[u]=++index; 38 stack[st++]=u; 39 instack[u]=true; 40 for(int e=head[u];e!=-1;e=edge[e].next){ 41 int v=edge[e].v; 42 if (dfn[v]==-1) { 43 Tarjan(v) ; 44 low[u] = min(low[u], low[v]) ; 45 } 46 else if (instack[v]) { 47 low[u] = min(low[u], dfn[v]) ; 48 } 49 } 50 int v; 51 if (dfn[u] == low[u]) { 52 beg++; 53 outdegree[beg]=indegree[beg]=0; 54 do{ 55 v=stack[--st]; 56 belong[v]=beg; 57 instack[v]=false; 58 }while(u!= v); 59 } 60 } 61 62 63 bool ok(int i,int j,int x,int y){ 64 if(i>=0&&i<x&&j>=0&&j<y) return true; 65 return false; 66 } 67 68 int main(){ 69 int x,y; 70 while(scanf("%d%d",&y,&x)!=EOF){ 71 for(int i=0;i<x;i++){ 72 for(int j=0;j<y;j++) 73 scanf("%d",&map[i][j]); 74 } 75 76 tot=index=st=beg=0; 77 int u,v,tx,ty; 78 int spoint=x*y; 79 for(int i=0;i<=spoint;i++){ 80 head[i]=dfn[i]=low[i]=belong[i]=-1; 81 instack[i]=false; 82 } 83 84 for(int i=0;i<x;i++){ 85 for(int j=0;j<y;j++){ 86 u=i*y+j; 87 for(int k=0;k<4;k++){ 88 tx=i+dir[k][0]; 89 ty=j+dir[k][1]; 90 if(ok(tx,ty,x,y)){ 91 if(map[tx][ty]<=map[i][j]){ 92 v=tx*y+ty; 93 addedge(u,v); 94 } 95 } 96 } 97 } 98 } 99 100 for(int i=0;i<spoint;i++){ 101 if(dfn[i]==-1){ 102 Tarjan(i); 103 } 104 } 105 106 for(int i=0;i<spoint;i++){ 107 u=i; 108 for(int e=head[u];e!=-1;e=edge[e].next){ 109 v=edge[e].v; 110 if(belong[u]!=belong[v]){ 111 outdegree[belong[u]]++; 112 indegree[belong[v]]++; 113 } 114 } 115 } 116 117 int ou=0,in=0; 118 if(beg==1){ 119 puts("0"); 120 continue; 121 } 122 for(int i=1;i<=beg;i++){ 123 if(outdegree[i]==0){ 124 ou++; 125 } 126 if(indegree[i]==0) 127 in++; 128 } 129 130 printf("%d\n",max(ou,in)); 131 } 132 return 0; 133 }