zoukankan      html  css  js  c++  java
  • POJ 2375 Cow Ski Area[连通分量]

    题目链接:http://poj.org/problem?id=2375
    题目大意:一片滑雪场,奶牛只能向相邻的并且不高于他当前高度的地方走。想加上缆车是的奶牛能从低的地方走向高的地方,
    求最少加的缆车数,是的奶牛可以从任意一个角落到达任意另外的角落
    解题思路:奶牛可以向相邻的不高于他的地方走,相当于u,v之前连通。若想加上缆车是图成为连通图,
    数目就是max(root, leave);
    思路同POJ 1236

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    #define M 505
    #define N 2000005
    struct Edge
    {
        int v, next;
    }edge[N];
    
    int node[N], stack[N], instack[N], dfn[N], out[N], in[N];
    int low[N], belong[N], index, cnt_edge, n, m, cnt_tar, top;
    int ee[N][2];
    int map[M][M];
    int dir[4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    
    void add_Edge(int u, int v)
    {
        edge[cnt_edge].next=node[u];
        edge[cnt_edge].v=v;
        node[u]=cnt_edge++;
    }
    void tarjan(int u)
    {
        int i, j, v;
        dfn[u]=low[u]=++index;
        stack[++top]=u;
        instack[u]=1;
        for(i=node[u]; i!=-1; i=edge[i].next)
        {
            v=edge[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u], low[v]);
            }
            else if(instack[v])
                low[u]=min(low[u], dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            cnt_tar++;
            do
            {
                j=stack[top--];
                instack[j]=0;
                belong[j]=cnt_tar;
            }while(j!=u);
        }
    }
    void solve()
    {
        int i;
        top=0, index=0, cnt_tar=0;
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        for(i=1; i<=n; i++)
            if(!dfn[i])
                tarjan(i);
    }
    int main()
    {
        int i, ii, w, l, j, x, y;
        while(scanf("%d%d", &l, &w)!=EOF)
        {
            cnt_edge=0, m=1, n=l*w;
            memset(node, -1, sizeof(node));
            memset(in, 0, sizeof(in));
            memset(out, 0, sizeof(out));
            for(i=1; i<=w; i++)
            {
                for(j=1; j<=l; j++)
                    scanf("%d", &map[i][j]);
            }
            for(i=1; i<=w; i++)
                for(j=1; j<=l; j++)
                    for(ii=0; ii<4; ii++)
                    {
                        int x=i+dir[ii][0], y=j+dir[ii][1];
                        if(x>=1&&x<=w&&y>=1&&y<=l)
                        {
                            if(map[x][y]<=map[i][j])
                            {
                                add_Edge((i-1)*l+j, (x-1)*l+y);
                                ee[m][0]=(i-1)*l+j, ee[m++][1]=(x-1)*l+y;
                            }
                        }
                    }
            solve();
            for(i=1; i<=m; i++)
            {
                int xx=belong[ee[i][0]], yy=belong[ee[i][1]];
                if(xx!=yy)
                {
                    in[yy]++;
                    out[xx]++;
                }
            }
            int innum=0, outnum=0;
            for(i=1; i<=cnt_tar; i++)
            {
                if(in[i]==0)
                    innum++;
                if(out[i]==0)
                    outnum++;
            }
            if(cnt_tar==1)
                printf("0
    ");
            else
                printf("%d
    ", max(innum, outnum));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    零基础学习接口测试-接口文档
    零基础学习接口测试-HTTP消息结构
    零基础学习接口测试—HTTP协议基础知识
    零基础学习接口测试-接口测试基础知识
    MySQL数据库安装
    软件测试基础-软件测试基本流程
    零基础学习接口测试-HTTPS协议
    软件测试基础-软件测试分类
    BLE5.2 CIS Data Flush Point点SN和NESN变化机制探讨
    使用Jlink给CC2640R2F烧写固件方法
  • 原文地址:https://www.cnblogs.com/Hilda/p/3226721.html
Copyright © 2011-2022 走看看