zoukankan      html  css  js  c++  java
  • [POI2007]POW-The Flood

    题目描述

    给定一张地势图,所有的点都被水淹没,现在有一些关键点,要求放最少的水泵使所有关键点的水都被抽干

    输入输出格式

    输入格式:

    In the first line of the standard input there are two integers  and , separated by a single space,. The following  lines contain the description of the map. The 'th linedescribes the 'th row ofunitary squares in the map. It contains  integers , separated by single spaces,.

    The number  describes the 'th square of the ![](http://main.edu.pl/images/OI14/pow-en-tex.14.pn

    输出格式:

    Your programme should write out one integer to the standard output - the minimum number of pumpsneeded to drain Byteburg.

    输入输出样例

    输入样例#1:
    6 9
    -2 -2 -1 -1 -2 -2 -2 -12 -3
    -2 1 -1 2 -8 -12 2 -12 -12
    -5 3 1 1 -12 4 -6 2 -2
    -5 -2 -2 2 -12 -3 4 -3 -1
    -5 -6 -2 2 -12 5 6 2 -1
    -4 -8 -8 -10 -12 -8 -6 -6 -4
    输出样例#1:
    2
    我们首先考虑如果在格子 a 修建一个抽水机,在什么情况下格子 b 的水也可以被抽干。
    我们可以发现当且仅当存在一条从 a 到 b 的路径,中间经过的抽水机(包括 a)的高度都不大于 b 的高度。
    即h[b]>=max(h[i])
    因此我们可以考虑把所有格子的高度从小到大排序,我们把每一个格子建成一个集合。
    然后按照海拔高度从小到大扫描格子,对于当前的格子 i,我们找到所有与 i 相邻并且海拔高度不大于格子 i 的格子,
    我们发现如果这些格子中的任意一个洪水要是被解决了,那么格子 i 的洪水也可以被解决,所以我们合并这些格子。
    对于当前的格子 i,如果它必须被清理且与它相邻的格子集合中没有任何一个被清理,我们则把这个集合的清理状态标记为真,然后答案加 1。
    集合和每个格子是否被清理用并查集来维护就可以了。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct node
     7 {
     8     int s,x,y;
     9 } city[1000001],maze[100001];
    10 pair<int,int> set[1001][1001];
    11 int dx[5]={0,1,-1,0,0};
    12 int dy[5]={0,0,0,1,-1};
    13 int n,m,a[1001][1001],tot,cnt,vis[1001][1001],ans;
    14 bool cmp(node a,node b)
    15 {
    16     return (a.s<b.s);
    17 }
    18 pair<int,int> find(pair<int,int> x)
    19 {
    20     if (set[x.first][x.second]!=x) set[x.first][x.second]=find(set[x.first][x.second]);
    21     return set[x.first][x.second];
    22 }
    23 void union_set(pair<int,int> x,pair<int,int> y)
    24 {
    25     x=find(x),y=find(y);
    26         set[x.first][x.second]=y;
    27         vis[y.first][y.second]|=vis[x.first][x.second];
    28 }
    29 void exam(int x,int y)
    30 {
    31     for(int i=1;i<=4;i++)
    32     {
    33         int tx=x+dx[i], ty=y+dy[i];
    34         if(tx<=0||ty<=0||tx>m||ty>n) continue;
    35         if(a[tx][ty]>a[x][y]) continue;
    36         union_set(make_pair(x, y), make_pair(tx, ty));
    37     }
    38 }
    39 int main()
    40 {
    41     int i,j;
    42     cin>>n>>m;
    43     for (i=1; i<=n; i++)
    44     {
    45         for (j=1; j<=m; j++)
    46         {
    47             scanf("%d",&a[i][j]);
    48             if (a[i][j]<=0)
    49             {
    50                 a[i][j]=-a[i][j];
    51             }
    52             else
    53             {
    54                 city[++tot]=(node){a[i][j],i,j};
    55             }
    56             maze[++cnt]=(node){a[i][j],i,j};
    57             set[i][j]=make_pair(i,j);
    58         }
    59     }
    60     sort(maze+1,maze+cnt+1,cmp);
    61     sort(city+1,city+tot+1,cmp);
    62     for (i=1; i<=tot; i++)
    63     {
    64         for (j=1; j<=cnt,city[i].s>=maze[j].s; j++)
    65         {
    66             exam(maze[j].x,maze[j].y);
    67             pair<int,int> x=find(make_pair(city[i].x,city[i].y));
    68             if (vis[x.first][x.second]==0)
    69             {
    70                 ans++;
    71                 vis[x.first][x.second]=1;
    72             }
    73         }
    74     }
    75     cout<<ans;
    76 }
  • 相关阅读:
    文件处理
    基本数据类型
    Python简介和入门
    了解计算机的发展历程
    工具类(MailUtils)发邮件
    文件上传和下载
    JavaWeb过滤器
    JavaWeb监听器
    JavaWeb的分页
    JdbcUtils(内部使用c3p0得到连接池对象datasource)的第三次修改---完成事务的处理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7221242.html
Copyright © 2011-2022 走看看