您的位置:首页 > 编程语言 > C语言/C++

Cpp环境【POJ 2375】【Vijos1642】雪场缆车

2016-07-15 18:14 218 查看
【问题描述】


  约翰的表哥罗恩生活在科罗拉多州。他进来打算教他的奶牛们滑雪,但是奶牛们非常害羞,不敢在游人如织的度假胜地滑雪。没办法,他只好自己建滑雪场了。

  罗恩的雪场可以划分为W列L行,每个方格都有一个特定的高度H。奶牛可以在相邻邻方格间滑雪,而且不能由低到高滑。

  为了保证任意方格可以互通,罗恩打算造一些直达缆车。缆车很强大,可以连接任意两个方格,而且是双向的。而且同一个方格可以造多台缆车。但是缆车的建造费用贵的吓人,所以他希望造尽量少的缆车。那最少需要多少台呢?

【输入格式】


  第一行:W和L

  接下来是W*H的矩阵地图。

【输出格式】


  最小的缆车数

【输入样例】


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

【输出样例】


3

【样例解释】


  把左下角作为(1,1),建立(3,1) <->(8,2),(7,3)<->(5,2),(1,3)<->(2,2)三部缆车,这样任意两个格子可以互通。

【数据范围】


1<=W<=500;1<=L<=500

0<=H<=9999

【来源】


POJ 2375

【思路梳理】


运用缩点的思想,可以将每一片高度相同的区域可以都看做是一个连通分量,那么在输入图之后对整张图进行处理。因为只能由高度不低于该点的格子移动过来,那么我们可以从高度更高的区域向低的区域连一条有向边。添加缆车就是加一条无向边,使得两个端点所处的区域相互连通。由此观之,我们要向整个图中添加无向边(准确来说应该是双向有向边),使得有向图中所有的连通分量都全部相互强连通。给出cpp代码如下。

【Cpp代码】


#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#define maxn 505
using namespace std;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct loca
{
int x,y;
};
int w,l,height[maxn][maxn],belong[maxn][maxn],scc=0;
int cd[maxn*maxn],rd[maxn*maxn];
vector<int>g[maxn*maxn];

void read(int &x)
{
x=0;char ch=getchar();
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
}

loca q[250005];int front,rear;
void BFS(int x,int y,int scc)
{
front=rear=1;
q[rear++]=(loca){x,y};
belong[x][y]=scc;

while(front!=rear)
{
x=q[front].x,y=q[front].y;front++;

for(int i=0;i<4;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(belong[xx][yy] || xx<1 || xx>w || yy<1 || yy>l)  continue;
if(height[xx][yy]==height[x][y])
{
q[rear++]=(loca){xx,yy};
belong[xx][yy]=scc;
}
}
}
}

int main()
{
//  freopen("in.txt","r",stdin);
read(l);read(w);
for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)   read(height[i][j]);

for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)if(!belong[i][j])
BFS(i,j,++scc);

for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)
for(int k=0;k<4;k++)
{
int x=i+dx[k],y=j+dy[k];
if(x>w || x<1 || y>l || y<1)    continue;
if(height[x][y]<height[i][j])
{
cd[belong[i][j]]++;
rd[belong[x][y]]++;
}
else if(height[x][y]>height[i][j])
{
rd[belong[i][j]]++;
cd[belong[x][y]]++;
}
}

int a=0,b=0,ans=0;
for(int i=1;i<=scc;i++)
{
if(rd[i]==0)    a++;
if(cd[i]==0)    b++;
}
if(scc==1)  ans=0;
else ans=max(a,b);
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息