POJ 2375 强连通分量

                                                                                            Cow Ski Area











Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 1888Accepted: 563

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.

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.

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.
解题思路:将每个方格作为一个点,与上下左右符合条件的点连边,然后tarjin缩点,取找出强连通分量,取入度,出度最大值,特判:假设只有一个连通分量的时候,答案为0;
代码:
  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 #include<map>
  6 #include<vector>
  7 using namespace std;
  8 const int maxn=1000000;
  9 const int maxm=5000000;
 10 int head[maxn],tol,low[maxn],dfn[maxn],belong[maxn],in[maxn],out[maxn],Stack[maxn],instack[maxn],top,indexx,scc;
 11 struct node
 12 {
 13         int next,to;
 14 }edge[maxm];
 15 void add(int u,int v)
 16 {
 17         edge[tol].to=v;
 18         edge[tol].next=head[u];
 19         head[u]=tol++;
 20 }
 21 void tarjin(int u)
 22 {
 23         low[u]=dfn[u]=++indexx;
 24         Stack[top++]=u;instack[u]=1;
 25         int i,v;
 26         for(i=head[u];i!=-1;i=edge[i].next)
 27         {
 28                 v=edge[i].to;
 29                 if(!dfn[v])
 30                 {
 31                         tarjin(v);
 32                         if(low[u]>low[v])low[u]=low[v];
 33                 }
 34                 else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
 35         }
 36         if(low[u]==dfn[u])
 37         {
 38                 scc++;
 39                 do
 40                 {
 41                         v=Stack[--top];
 42                         instack[v]=0;
 43                         belong[v]=scc;
 44                 }while(u!=v);
 45         }
 46 }
 47 void solve(int n)
 48 {
 49         memset(instack,0,sizeof(instack));
 50         memset(dfn,0,sizeof(dfn));
 51         memset(belong,0,sizeof(belong));
 52         indexx=scc=top=0;
 53         int u,i,v;
 54         for(i=0;i<n;i++)if(!dfn[i])tarjin(i);
 55         if(scc==1)
 56         {
 57                 puts("0");return;
 58         }
 59         memset(in,0,sizeof(in));
 60         memset(out,0,sizeof(out));
 61         for(u=0;u<n;u++)
 62         {
 63                 for(i=head[u];i!=-1;i=edge[i].next)
 64                 {
 65                         v=edge[i].to;
 66                         if(belong[u]==belong[v])continue;
 67                         in[belong[v]]++;
 68                         out[belong[u]]++;
 69                 }
 70         }
 71         int ans1=0,ans2=0;
 72         for(i=1;i<=scc;i++)
 73         {
 74                 if(in[i]==0)ans1++;
 75                 if(out[i]==0)ans2++;
 76         }
 77         printf("%d\n",max(ans1,ans2));
 78 }
 79 int height[600][600];
 80 int dx[]={0,0,1,-1};
 81 int dy[]={1,-1,0,0};
 82 int main()
 83 {
 84         int i,j,k,m,n,p,q;
 85         while(~scanf("%d%d",&m,&n))
 86         {
 87                 for(i=0;i<n;i++)
 88                 for(j=0;j<m;j++)
 89                 scanf("%d",&height[i][j]);
 90                 memset(head,-1,sizeof(head));
 91                 tol=0;
 92                 for(i=0;i<n;i++)
 93                 for(j=0;j<m;j++)
 94                 {
 95                         p=i*m+j;
 96                         for(k=0;k<4;k++)
 97                         {
 98                                 int nx=i+dx[k];
 99                                 int ny=j+dy[k];
100                                 q=nx*m+ny;
101                                 if(nx>=0&&nx<n&&ny>=0&&ny<m&&height[i][j]>=height[nx][ny])add(p,q);
102                         }
103                 }
104                // cout<<tol<<endl;
105                n*=m;
106                //cout<<n<<endl;
107                solve(n);
108         }
109         return 0;
110 }
posted @ 2013-09-01 22:05  线性无关  阅读(152)  评论(0)    收藏  举报