POJ2375 Cow Ski Area 【强连通分量】+【DFS】

POJ2375 Cow Ski Area 【强连通分量】+【DFS】CowSkiAreaTimeLimit: 1000MS MemoryLimit: 65536KTotalSubmissions: 2323 Accepted: 660DescriptionFarmerJohn’scousin,FarmerRon,wholivesinthemountainsof

大家好,又见面了,我是你们的朋友全栈君。

Cow Ski Area
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2323   Accepted: 660

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.

Source

题意:本题描述了一片滑雪场,并且规定奶牛从一个点只能向它相邻的并且高度不大于它的点运动,现在想要在某些点对之间加上缆车使得奶牛也可以从较低点到达较高点,问最少需要多少辆这样的缆车就可以使得奶牛可以从任意一个点运动到滑雪场的每个角落。

解:对于相邻的高度相同的点,实际上路线是双向的,所以它们构成了强连通,然后这道题可以找出所有强连通,于是就构成了一个DAG,然后答案就是max(入度为0的点,出度为0的点),特别的,当整幅图已经是强连通时答案为0.这题求强连通可以用DFS,省去不少麻烦。

#include <stdio.h>
#include <string.h>
#define maxn 502

int map[maxn][maxn], scc[maxn][maxn];
int sccNum, id, head[maxn * maxn], n, m;
bool in[maxn * maxn], out[maxn * maxn];
struct Node{
    int to, next;
} E[maxn * maxn << 2];

void addEdge(int u, int v)
{
    E[id].to = v;
    E[id].next = head[u];
    head[u] = id++;
}

void getMap(int n, int m)
{
    int i, j; id = 0;
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j)
            scanf("%d", &map[i][j]);
}

void DFS(int x, int y)
{
    if(scc[x][y]) return;
    scc[x][y] = sccNum;    
    if(x + 1 <= n && map[x+1][y] == map[x][y]) DFS(x + 1, y);
    if(x - 1 >= 0 && map[x-1][y] == map[x][y]) DFS(x - 1, y);
    if(y + 1 <= m && map[x][y+1] == map[x][y]) DFS(x, y + 1);
    if(y - 1 >= 0 && map[x][y-1] == map[x][y]) DFS(x, y - 1);
}

void solve(int n, int m)
{
    memset(scc, 0, sizeof(scc));
    memset(in, 0, sizeof(in));
    memset(out, 0, sizeof(out));
    memset(head, -1, sizeof(head));
    sccNum = 0;
    int i, j, ans1 = 0, ans2 = 0;
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j)
            if(!scc[i][j]){
                ++sccNum; DFS(i, j);
            }
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j){
            if(i + 1 <= n && scc[i][j] != scc[i+1][j]){
                if(map[i][j] > map[i+1][j]){
                    addEdge(scc[i][j], scc[i+1][j]);
                    in[scc[i+1][j]] = out[scc[i][j]] = 1;
                } else{
                    addEdge(scc[i+1][j], scc[i][j]);
                    in[scc[i][j]] = out[scc[i+1][j]] = 1;
                }
            }
            if(j + 1 <= m && scc[i][j] != scc[i][j+1]){
                if(map[i][j] > map[i][j+1]){
                    addEdge(scc[i][j], scc[i][j+1]);
                    in[scc[i][j+1]] = out[scc[i][j]] = 1;
                } else{
                    addEdge(scc[i][j+1], scc[i][j]);
                    in[scc[i][j]] = out[scc[i][j+1]] = 1;
                }
            }
        }
    if(sccNum != 1)
        for(i = 1; i <= sccNum; ++i){
            if(!in[i]) ++ans1;
            if(!out[i]) ++ans2;
        }
    if(ans1 < ans2) ans1 = ans2;
    printf("%d\n", ans1);
}

int main()
{
    while(scanf("%d%d", &m, &n) == 2){
        getMap(n, m);
        solve(n, m);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143743.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一世12年龄在泥土还在打,硅谷00创业毕竟开始播放!

    一世12年龄在泥土还在打,硅谷00创业毕竟开始播放!

    2022年1月3日
    56
  • 游标和动态SQL

    游标和动态SQL游标类别:静态游标(指在编译的时候,游标就与一个select语句进行了静态绑定的游标,这种游标只能作用于一个查询语句)和动态游标(就是希望我们的查询语句在运行的时候才跟游标绑定,为了使用动态游标,必须声明游标变量)。动态游标分两种,分别是强类型和弱类型。强类型的动态游标只能支持查询结果与他类型匹配的这种查询语句,弱类型的动态游标可以支持任何的查询语句。静态游标分为两种,隐式游标和显

    2022年6月23日
    28
  • mysql的字符串拼接函数怎么用_拼接字段的函数是什么

    mysql的字符串拼接函数怎么用_拼接字段的函数是什么MySQL的字符串拼接有三个函数CONCAT(str1,str2,…)CONCAT_WS(separator,str1,str2,…)GROUP_CONCAT(expr)这三个函数都各有作用,现在测试看看是什么样子的效果准备数据表CREATETABLE`user_info`(`id`int(11)NOTNULLAUTO_INCREMENT,`name`varchar(255)DEFAULTNULL,`age`int(3)DEFAULTNULL,

    2025年7月13日
    2
  • IOS学习随笔三

    IOS学习随笔三IOS学习随笔三

    2022年4月22日
    46
  • 火狐浏览器丢失书签,恢复无法处理备份文件的解决方案

    火狐浏览器丢失书签,恢复无法处理备份文件的解决方案

    2021年10月17日
    51
  • JAVA对象转JSON字符串时格式化日期_oracle clob转字符串

    JAVA对象转JSON字符串时格式化日期_oracle clob转字符串本案例所有代码均为原创,使用Java手写,没有借鉴其他类似工具库和网上论坛博客,也许没有经过充分测试,可能出现未知bug,因此不建议拿到正式的项目里使用。Java对象就像一个文件夹一样,没有办法知道其深度,所以采用了递归。性能方面没有测试,个人认为没有特别耗费性能的地方,除非你的对象包含很多层级。它可以支持null,字符串,数字、日期、集合等多种类型,包括以上类型的多层嵌套,都没有问题。源码不多,如下:importjava.lang.reflect.Field;importjava.lang

    2022年9月21日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号