BFS+强连通。输出max(缩点后出度为0的点数,缩点后入度为0的点数)。
#include
#include
#include
#include
#include
#define LL unsigned __int64
using namespace std;
const int N= ;
struct Edge{
int u,v;
int next;
}edge[N*];
int tot,index;
int head[N],dfn[N],low[N],stack[N],st;
int outdegree[N],indegree[N];
int belong[N],beg;
bool instack[N];
int map[][];
int dir[][]={
{,},
{,-},
{,},
{-,}
};
void addedge(int u,int v){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void Tarjan(int u) {
dfn[u]=low[u]=++index;
stack[st++]=u;
instack[u]=true;
for(int e=head[u];e!=-;e=edge[e].next){
int v=edge[e].v;
if (dfn[v]==-) {
Tarjan(v) ;
low[u] = min(low[u], low[v]) ;
}
else if (instack[v]) {
low[u] = min(low[u], dfn[v]) ;
}
}
int v;
if (dfn[u] == low[u]) {
beg++;
outdegree[beg]=indegree[beg]=;
do{
v=stack[--st];
belong[v]=beg;
instack[v]=false;
}while(u!= v);
}
}
bool ok(int i,int j,int x,int y){
if(i>=&&i
return false;
}
int main(){
int x,y;
while(scanf("%d%d",&y,&x)!=EOF){
for(int i=;i<x;i++){
for(int j=;j<y;j++)
scanf("%d",&map[i][j]);
}
tot=index=st=beg=;
int u,v,tx,ty;
int spoint=x\*y;
for(int i=;i<=spoint;i++){
head\[i\]=dfn\[i\]=low\[i\]=belong\[i\]=-;
instack\[i\]=false;
}
for(int i=;i<x;i++){
for(int j=;j<y;j++){
u=i\*y+j;
for(int k=;k<;k++){
tx=i+dir\[k\]\[\];
ty=j+dir\[k\]\[\];
if(ok(tx,ty,x,y)){
if(map\[tx\]\[ty\]<=map\[i\]\[j\]){
v=tx\*y+ty;
addedge(u,v);
}
}
}
}
}
for(int i=;i<spoint;i++){
if(dfn\[i\]==-){
Tarjan(i);
}
}
for(int i=;i<spoint;i++){
u=i;
for(int e=head\[u\];e!=-;e=edge\[e\].next){
v=edge\[e\].v;
if(belong\[u\]!=belong\[v\]){
outdegree\[belong\[u\]\]++;
indegree\[belong\[v\]\]++;
}
}
}
int ou=,in=;
if(beg==){
puts("");
continue;
}
for(int i=;i<=beg;i++){
if(outdegree\[i\]==){
ou++;
}
if(indegree\[i\]==)
in++;
}
printf("%d\\n",max(ou,in));
}
return ;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章