Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2153 | Accepted: 614 |
Description
private ski area behind his farm.
FR's ski area is a rectangle of width W and length L of 'land squares' (1 <= W <= 500; 1 <= L <= 500). Each land square is an integral height H above sea level (0 <= H <= 9,999). Cows can ski horizontally and vertically between any two adjacent land squares,
but never diagonally. Cows can ski from a higher square to a lower square but not the other way and they can ski either direction between two adjacent squares of the same height.
FR wants to build his ski area so that his cows can travel between any two squares by a combination of skiing (as described above) and ski lifts. A ski lift can be built between any two squares of the ski area, regardless of height. Ski lifts are bidirectional.
Ski lifts can cross over each other since they can be built at varying heights above the ground, and multiple ski lifts can begin or end at the same square. Since ski lifts are expensive to build, FR wants to minimize the number of ski lifts he has to build
to allow his cows to travel between all squares of his ski area.
Find the minimum number of ski lifts required to ensure the cows can travel from any square to any other square via a combination of skiing and lifts.
Input
* Lines 2..L+1: L lines, each with W space-separated integers corresponding to the height of each square of land.
Output
Sample Input
9 3 1 1 1 2 2 2 1 1 1 1 2 1 2 3 2 1 2 1 1 1 1 2 2 2 1 1 1
Sample Output
3
Hint
OUTPUT DETAILS:
FR builds the three lifts. Using (1, 1) as the lower-left corner,
the lifts are (3, 1) <-> (8, 2), (7, 3) <-> (5, 2), and (1, 3) <->
(2, 2). All locations are now connected. For example, a cow wishing
to travel from (9, 1) to (2, 2) would ski (9, 1) -> (8, 1) -> (7,
1) -> (7, 2) -> (7, 3), take the lift from (7, 3) -> (5, 2), ski
(5, 2) -> (4, 2) -> (3, 2) -> (3, 3) -> (2, 3) -> (1, 3), and then
take the lift from (1, 3) - > (2, 2). There is no solution using
fewer than three lifts.
Source
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <numeric> #include <iomanip> #include <bitset> #include <list> #include <stdexcept> #include <functional> #include <utility> #include <ctime> using namespace std; #define PB push_back #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define DWN(i,h,l) for(int i=(h);i>=(l);--i) #define CLR(vis) memset(vis,0,sizeof(vis)) #define MST(vis,pos) memset(vis,pos,sizeof(vis)) #define MAX3(a,b,c) max(a,max(b,c)) #define MAX4(a,b,c,d) max(max(a,b),max(c,d)) #define MIN3(a,b,c) min(a,min(b,c)) #define MIN4(a,b,c,d) min(min(a,b),min(c,d)) #define PI acos(-1.0) #define INF 0x7FFFFFFF #define LINF 1000000000000000000LL #define eps 1e-8 typedef long long ll; const int maxn=250005; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int mp[555][555]; struct node{ int u,to,next; }e[maxn*8]; int head[maxn],edge; int id[maxn],q[maxn],dfn[maxn],low[maxn],num[maxn]; int n,m,tsp,qe,cnt; void init() { MST(head,-1); edge=0; } void addedge(int u,int v) { e[edge].u=u; e[edge].to=v; e[edge].next=head[u]; head[u]=edge++; } void tarjan(int u) { int i,v; dfn[u]=low[q[qe++]=u]=++tsp; for(i=head[u];i>=0;i=e[i].next) if(!dfn[v=e[i].to]) { tarjan(v); low[u]=min(low[u],low[v]); } else { if(id[v]<0) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { num[id[u]=++cnt]=1; while((v=q[--qe])!=u) ++num[id[v]=cnt]; } } void solve() { int i; tsp=qe=cnt=0; for(i=0;i<=n;++i) id[i]=-1,dfn[i]=0; for(i=1;i<=n;++i) if(!dfn[i]) tarjan(i); } int main() { int w,l; cin>>w>>l; CLR(mp); FOR(i,1,l) FOR(j,1,w) scanf("%d",&mp[i][j]); int u,v,x,y; init(); FOR(i,1,l) { FOR(j,1,w) { u=(i-1)*w+j; REP(k,4) { x=i+dir[k][0]; y=j+dir[k][1]; v=(x-1)*w+y; if(x<1 || x>l || y<1 || y>w) continue; if(mp[i][j]>=mp[x][y]) addedge(u,v); if(mp[i][j]<=mp[x][y]) addedge(v,u); } } } n=l*w; solve(); if(cnt==1) { cout<<0<<endl; return 0; } int out[maxn],in[maxn]; CLR(out),CLR(in); REP(i,edge) { int u=id[e[i].u],v=id[e[i].to]; if(u!=v) in[v]++,out[u]++; } int a=0,b=0; FOR(i,1,cnt) { if(!in[i]) a++; if(!out[i]) b++; } cout<<max(a,b)<<endl; return 0; }