题意:奶牛可以向相邻的并且海拔不大于的位置进行移动,现在要添加缆车,可以试想从低处向高处行进,问最少添加多少个?
解法:
奶牛的运动:向相同的点(双向),向低处(单向)-> 缩点,然后会使整个图成为有向图强连通图,Max(入度为0的个数,初度为0的个数),特别的当连通分量只有一个的时候输出0。
根据本题的性质,强连通分量都是高度相同的连通区域,对于这些区域BFS就可以试想缩点,提高效率。
/*
----------------------------------
Love is more than a word.
It says so much.
When I see these four letters,
I almost feel your touch.
This is only happened since
I fell in love with you.
Why this word does this,
I haven't got a clue.
To My Goddess
CY
----------------------------------
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 550+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define clehead(a) rep(i,maxn)a[i]=-1
/*
The time of story :
** while(1)
{
once upon a time,
there was a mountain,
on top of which there was a temple,
in which there was an old monk and a little monk.
Old monk was telling stories inside the temple.
What was he talking about?
** }
ÎûÎû
(*^__^*)
*/
#define sci(a) scanf("%d",&a)
#define scd(a) scanf("%lf",&a)
#define pri(a) printf("%d",a)
#define prie(a) printf("%d\n",a)
#define prd(a) printf("%lf",a)
#define prde(a) printf("%lf\n",a)
#define pre printf("\n")
#define LL(x) x<<1
#define RR(x) x<<|1
#define pb push_back
#define mod 90001
#define PI 3.141592657
const ull INF = 1LL << 61;
const int inf = int(1e5)+10;
const double eps=1e-5;
using namespace std;
struct node
{
int u,v,w;
int next;
};
int w,l;
int val[maxn][maxn];
int scc_num;
int used[maxn][maxn];
int belong[maxn][maxn];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int in[2555000];
int out[2555000];
void init()
{
cle(used);
scc_num=0;
cle(belong);
}
bool getbool(int x,int y)
{
if(x<0||y<0)return false;
if(x>=l||y>=w)return false;
return true;
}
bool cmp(int a,int b){
return a>b;
}
void bfs(int x,int y)
{
int i,j,k;
if(getbool(x,y)==false)return;
used[x][y]=1;
belong[x][y]=scc_num;
for(i=0;i<4;i++)
{
int tempx=x+dir[i][0];
int tempy=y+dir[i][1];
if(getbool(tempx,tempy)&&val[tempx][tempy]==val[x][y]&&used[tempx][tempy]==0)
{
bfs(tempx,tempy);
}
}
return ;
}
void doit()
{
int i,j,k;
for(i=0;i<l;i++)
{
for(j=0;j<w;j++)
{
for(k=0;k<4;k++)
{
int x,y;
x=i+dir[k][0];
y=j+dir[k][1];
if(getbool(x,y)&&belong[i][j]!=belong[x][y]&&val[x][y]<=val[i][j])
{
out[belong[x][y]]++;
in[belong[i][j]]++;
}
}
}
}
}
int main()
{
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i,j,k;
while(cin>>w>>l)
{
init();
for(i=0;i<l;i++)
{
for(j=0;j<w;j++)
{
scanf("%d",&val[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<w;j++)
{
if(used[i][j]==0)
{
scc_num++;
bfs(i,j);
}
}
}
cle(in);
cle(out);
doit();
int ans1=0;
int ans2=0;
int ans=0;
for(i=1;i<=scc_num;i++)
{
if(in[i]==0)
{
ans1++;
}
if(out[i]==0)
{
ans2++;
}
}
if(scc_num==1)cout<<0<<endl;
else cout<<max(ans1,ans2)<<endl;
}
return 0;
}