NOIP2010引水入城题解

点击跟博主一起玩(zuo)耍(si)
首先这道题考验的并不是代码能力而是细心程度。仔细读题,你会发现对于每一个城市,如果要建水利设施,必须存在一个与它有公共边的比它高的城市才可以。运用贪心的算法,每次选取最高的靠近湖泊的城市进行搜索,当所有的干旱城市都建有水利设施的时候停止。当所有的靠近湖泊城市都建造了输水站而还有干旱城市没有满足条件时,需要for一遍干旱城市输出多少个没有建造水利设施。
那么接下来我们来证明一下贪心的正确性。
NOIP2010引水入城题解_第1张图片
如上图。当干旱城市需要建造水利设施时一定存在一个有公共边的比它海拔高的城市。那么当从最高点开始搜索时,保证最少能覆盖一个靠近湖泊的城市,从而减少>=1个输水站的建造。
代码如下

#include
#include
#include

using namespace std;
struct factory{
     long l,r;
}p[501];

long n,m,map[501][501],f[501],cnt=0;

bool vis[501][501]={0},ans[501]={0};


bool comp(const factory &a,const factory &b)
{
    return a.lvoid dfs(long x,long y,long ori)
{
     vis[x][y]=1;
     if(x==m){
          ans[y]=1;
          p[ori].l=min(p[ori].l,y);
          p[ori].r=max(p[ori].r,y);
     }
     if(map[x+1][y]<map[x][y]&&x!=m&&!vis[x+1][y])dfs(x+1,y,ori);
     if(map[x-1][y]<map[x][y]&&x!=1&&!vis[x-1][y])dfs(x-1,y,ori);
     if(map[x][y+1]<map[x][y]&&y!=n&&!vis[x][y+1])dfs(x,y+1,ori);
     if(map[x][y-1]<map[x][y]&&y!=1&&!vis[x][y-1])dfs(x,y-1,ori);
}

int main()
{
     cin>>m>>n;
     for(long i=1;i<=n;++i)p[i].l=f[i]=30000;
     f[0]=0;
     for(long i=1;i<=m;++i)
          for(long j=1;j<=n;++j)cin>>map[i][j];
     for(long i=1;i<=n;++i){
          dfs(1,i,i);
          memset(vis,0,sizeof(vis));
     }
     for(long i=1;i<=n;++i)
          if(!ans[i])++cnt;
     if(cnt)cout<<0<else{
          cout<<1<for(long i=1;i<=n;++i)
               for(long j=1;j<=n;++j){
                    if(i>=p[j].l&&i<=p[j].r)f[i]=min(f[i],f[p[j].l-1]+1);
              }
     cout<return 0;
}

你可能感兴趣的:(NOIP)