用bfs将连着的相同高度的山坡缩为1个点,再由较高的点向较低的点做有向边,最后MAX(没有入度的点 ,
,没有出度的点)即为所需边数。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int qx[300000+3],qy[300000+3];
int a[500+3][500+3],lx[500+3][500+3],rx[500+3][500+3],fa[500+3][500+3];
int Sl[300000+3],Sr[300000+3];
int U[2000000+3],V[2000000+3],ss[2000000+3],xh[2000000+3];
bool vis[500+3][500+3];
int n,m,nn,en;
const int tx[4]={1,-1,0,0};
const int ty[4]={0,0,1,-1};
bool comp(const int &A,const int &B)
{
return U[A]<U[B]||(U[A]==U[B]&&V[A]<V[B]);
}
void Bfs(int sx,int sy)
{
qx[1]=sx,qy[1]=sy;
fa[sx][sy]=++nn;
vis[sx][sy]=true;
for (int l=0,r=1;l<r;)
{
int x=qx[++l],y=qy[l];fa[x][y]=nn;
for (int i=0;i<4;i++)
{
int x3=x+tx[i],y3=y+ty[i];
if (x3<1||y3<1||x3>n||y3>m) continue;
if (vis[x3][y3]) continue;
if (a[x][y]==a[x3][y3])
{
qx[++r]=x3,qy[r]=y3;
vis[x3][y3]=true;
}
}
}
}
void work()
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (!fa[i][j])
Bfs(i,j);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
for (int k=0;k<4;k++)
{
int x=i+tx[k],y=j+ty[k];
if (x<1||y<1||x>n||y>m) continue;
if (a[i][j]>=a[x][y]) continue;
U[++en]=fa[i][j];
V[en]=fa[x][y];
}
for (int i=1;i<=en;i++)
{
Sl[U[i]]++;
Sr[V[i]]++;
}
int L=0,R=0;
for (int i=1;i<=nn;i++)
{
if (!Sl[i]) L++;
}
printf("%d",max(L,R));
}
int main()
{
scanf("%d%d",&m,&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (a[i][j]!=a[1][1])
{
work();return 0;
}
printf("0");
return 0;
}
,没有出度的点)即为所需边数。