Cow Ski Area
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1977 | Accepted: 580 |
Description
Farmer John's cousin, Farmer Ron, who lives in the mountains of Colorado, has recently taught his cows to ski. Unfortunately, his cows are somewhat timid and are afraid to ski among crowds of people at the local resorts, so FR has decided to construct his own 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.
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
* Line 1: Two space-separated integers: W and L
* Lines 2..L+1: L lines, each with W space-separated integers corresponding to the height of each square of land.
* Lines 2..L+1: L lines, each with W space-separated integers corresponding to the height of each square of land.
Output
* Line 1: A single integer equal to the minimal number of ski lifts FR needs to build to ensure that his cows can travel from any square to any other square via a combination of skiing and ski lifts
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
This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.
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.
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
题意是说在m*n的农场里,奶牛能从一个点只能向它相邻的并且高度不大于它的点运动,现在想要在某些点对之间加上缆车使得奶牛也可以从较低点向较高点运动,问最少需要多少辆这样的缆车就可以使得奶牛可以从一个点运动到滑雪场的每个角落。
在滑雪场高度相同且又相邻的点很特殊,因为可以互相达到,也就是说只要到达其中一个,则整个高度相同的连通区域都能到达,所以要用强连通来做。而此题求的是在有向图中最少加几条边使得整个有向图强连通。因此,只要算出强连通缩点后,图中入度为0的点个数以及出度为0的点个数,取二者较大值即可。当只有一个强连通分量时,答案为0.此题和POJ1236的第二问一样。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define M 250010
#define inf 0x3f3f3f
using namespace std;
int dfn[M],low[M],stack[M],vis[M],head[M],ans[M];
int g[507][507],belong[M],indegree[M],outdegree[M];
int dir[4][2]={1,0,0,1};
int n,m,cnt,num,id,tot;
struct E
{
int v,next;
}edg[M*8];
void addedge(int u,int v)
{
edg[cnt].v=v;
edg[cnt].next=head[u];
head[u]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(indegree,0,sizeof(indegree));
memset(outdegree,0,sizeof(outdegree));
cnt=num=id=tot=0;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
stack[id++]=x;
int v;
vis[x]=1;
for(int u=head[x];u!=-1;u=edg[u].next)
{
v=edg[u].v;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(vis[v])
low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x])
{
num++;
do
{
v=stack[--id];
belong[v]=num;
vis[v]=0;
}while(v!=x);
}
}
void slove()
{
for(int i=0;i<n*m;i++)
for(int j=head[i];j!=-1;j=edg[j].next)
{
int v=edg[j].v;
if(belong[i]!=belong[v])
{
indegree[belong[v]]++;
outdegree[belong[i]]++;
}
}
int inde=0,outde=0;
for(int i=1;i<=num;i++)
{
if(!indegree[i])inde++;
if(!outdegree[i])outde++;
}
if(num==1)
printf("0\n");
else
printf("%d\n",max(inde,outde));
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&g[i][j]);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
int t1=i*m+j;
for(int k=0;k<2;k++)
{
int xx=i+dir[k][0];
int yy=j+dir[k][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m)
{
int t2=xx*m+yy;
if(g[i][j]>=g[xx][yy])
addedge(t1,t2);
if(g[i][j]<=g[xx][yy])
addedge(t2,t1);
}
}
}
for(int i=0;i<n*m;i++)
if(!dfn[i])
tarjan(i);
slove();
}
return 0;
}