• POJ2375 Cow Ski Area (强连通)(缩点)


                                        Cow Ski Area
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 3323   Accepted: 919

    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
    SB题,还花了好长时间,不开心,不写题解了。
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <time.h>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #define inf 0x3f3f3f3f
    #define mod 10000
    typedef long long ll;
    using namespace std;
    const int N=505;
    const int M=250005;
    int s,t,n,m,cnt,tim,top,cut,k;
    int head[M],dfn[M],low[M],stack1[M];
    int num[M],in[M],out[M],vis[M],w[N][N];
    int dis[4][2]= {0,1,1,0,-1,0,0,-1};
    bool flag=false;
    struct man {
        int to,nxt;
    } edg[M*10];
    void addedg(int u,int v) {
        edg[cnt].to=v;
        edg[cnt].nxt=head[u];
        head[u]=cnt++;//printf("!!!%d %d
    ",u,v);system("pause");
    }
    void init() {
        cnt=0;
        tim=0;
        top=cut=k=0;
        memset(head,-1,sizeof head);
        memset(dfn,0,sizeof dfn);
        memset(low,0,sizeof low);
        memset(stack1,0,sizeof stack1);
        memset(num,0,sizeof num);
        memset(in,0,sizeof in);
        memset(out,0,sizeof out);
        memset(vis,0,sizeof vis);
        memset(edg,0,sizeof edg);
        memset(w,0,sizeof w);
    }
    void Tarjan(int u) {
        int v;
        low[u] = dfn[u] = ++tim;
        stack1[top++] = u;
        vis[u] = 1;
        for(int e = head[u]; e != -1; e = edg[e].nxt)
        {
            v = edg[e].to;
            if(!dfn[v])
            {
                Tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(vis[v])
            {
                low[u] = min(low[u], dfn[v]);
            }
        }
        if(low[u] == dfn[u])
        {
            cut++;
            do
            {
                v = stack1[--top];
                num[v] = cut;
                vis[v] = 0;
            }while(u != v);
        }
    }
    void build(int i,int j,int d)
    {
        int xx=i+dis[d][0];
        int yy=j+dis[d][1];
        int u=i*m+j,v=xx*m+yy;
        if(xx>=0&&yy<m&&yy>=0&&xx<n){
            if(w[i][j]>=w[xx][yy])addedg(u,v);
            if(w[i][j]<=w[xx][yy])addedg(v,u);
        }
        return;
    }
    int main() {
        while(~scanf("%d%d",&m,&n)) {
            init();
            for(int i=0; i<n; i++) {
                for(int j=0; j<m; j++) {
                    scanf("%d",&w[i][j]);
                }
            }
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < m; j++) {
                    for(int d = 0; d < 2; d++) {
                        build(i,j,d);
                    }
                }
            }
            for(int i=0; i<n*m; i++)if(!dfn[i])Tarjan(i);
            for(int i=0; i<n*m; i++) {
                for(int j=head[i]; j!=-1; j=edg[j].nxt) {
                    int v=edg[j].to;
                    if(num[i]!=num[v])out[num[i]]++,in[num[v]]++;
                }
            }
            int father=0,son=0;
            for(int i=1; i<=cut; i++) {
                if(in[i]==0)father++;
                if(out[i]==0)son++;
            }
            if(cut==1)printf("0
    ");
            else printf("%d
    ",max(father,son));
        }
        return 0;
    }
  • 相关阅读:
    apt 安装 Oracle Java JDK
    apt 安装 tomcat
    apt安装mysql
    yum 常用命令
    Ubuntu apt-get 更换源
    没有解决不了的bug,静下心一步步排查,早上一个小时就找出问题了
    关于看书学习的一点感悟
    利用暗时间看好了六大原则,下面开始练习23种设计模式
    养成看书思考的习惯
    凡事预则立,有时候还是得不断的去巩固一些基础知识的
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/5893731.html
Copyright © 2020-2023  润新知