洪水填充

學習算法


洪水填充

  • 一種基本的搜索應用.一張圖上有多個區域,不同區域用不同區分,而同個區域皆為相同.找到種子點後從種子點出發.把種子點所屬的封閉區域用新方法填充.這就是洪水填充

hdu1312

#include <iostream>
using namespace std;
char mp[21][21];
int n = 0;
int m = 0;
int cnt;
void dfs(int row, int col)
{
    if (row < 0 || row >= n || col < 0 || col >= m || mp[row][col] == '#')
        return;
    cnt++;
    mp[row][col] = '#';
    dfs(row - 1, col);
    dfs(row + 1, col);
    dfs(row, col + 1);
    dfs(row, col - 1);
}
 
int main()
{
    while (cin >> m >> n)
    {
        if (n == 0 && m == 0)
            break;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                cin >> mp[i][j];
            }
        }
        cnt = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
 
                if (mp[i][j] == '@')
                    dfs(i, j);
            }
        }
        cout << cnt << endl;
    }
}

poj2227

  • 運用到最小堆的概念
#include <iostream>
#include <queue>
#include <cstring>
 
#define ll long long
using namespace std;
 
const int N = 300 + 10;
int mp[N][N];
bool visits[N][N];
int dict[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
 
struct nodes {
    int _x;int _y;int _h;
    friend bool operator < (nodes a,nodes b){
        return  a._h > b._h;
    }
};
 
priority_queue<nodes> pq;
 
void init(){
    while(!pq.empty()) pq.pop();
    nodes node;
    memset(visits,false,sizeof(visits));
 
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            // 從4周往內
            if(i == 0 || j == 0 || i == n-1 || j == m-1){
                visits[i][j] = true;
                node._x = i;
                node._y = j;
                node._h = mp[i][j];
                pq.push(node);
            }
        }
    }
}
 
void bfs(){
    init();
    nodes node_;
    ll a=0;
    while(!pq.empty()){
        nodes node = pq.top();
        pq.pop();
        for(int i=0;i<4;i++){
            int nx = node._x + dict[i][0];
            int ny = node._y + dict[i][1];
            if(0 <= nx && nx < n && 0 <= ny&& ny < m && !visits[nx][ny]){
                visits[nx][ny] = true;
                node_._x = nx;
                node_._y = ny;
                node_._h = mp[nx][ny];
                if(node_._h < node._h) {
                    a += (node._h - node_._h);
                    node_._h = node._h;
                }
                pq.push(node_);
            }
        }
    }
 
    cout << a << endl;
}
 
 
int main(){
    while(cin >> m >> n){
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                cin >> mp[i][j];
        bfs();
    }
}

P1514

#include <iostream>
#include <cstring>
using namespace std;
 
const int N = 500 + 10;
 
int n=0,m=0;
int current=0;
 
int mp[N][N];
bool visits[N][N];
pair<int,int> range[N];
 
int dict[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
 
void dfs(int x,int y,bool isReachable){
    visits[x][y] = true;
    if(x == n-1 && isReachable){
        range[current].first = min(range[current].first, y);
        range[current].second = max(range[current].second, y);
    }
    for(int i=0;i<4;i++){
        int nx = dict[i][0] + x;
        int ny = dict[i][1] + y;
        if(nx >= 0 && nx < n && ny >=0 && ny < m && !visits[nx][ny] && mp[x][y] > mp[nx][ny]){
            dfs(nx,ny,isReachable);
        }
    }
}
 
 
void init(){
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> mp[i][j];
        }
    }
}
 
int main(){
    while(cin >> n >> m ){
        init();
        for (int i = 0; i < m; i++)
            dfs(0, i, false);
        int un_reachable_cnt = 0;
        for (int i = 0; i < m; i++)
            if (!visits[n - 1][i])
                un_reachable_cnt++;
        if (un_reachable_cnt > 0)
        {
            cout << 0 << '\n'
                << un_reachable_cnt;
            return 0;
        }
 
        for(int i=0;i<m;i++){
            memset(visits,false,sizeof(visits));
            current = i;
            range[current].first = 501;
            if(n == 1)
                dfs(0,i,true);
            else if(mp[0][i] > mp[1][i])
                dfs(1,i,true);
        }
 
        int maxRightBound;
        current = -1;
        while(current < m - 1){
            maxRightBound = -1;
            for(int i=0;i<m;i++){
                if(range[i].first <= current+1 && range[i].second > maxRightBound)
                    maxRightBound = range[i].second;
            }
            un_reachable_cnt++;
            current = maxRightBound;
        }
 
        cout << 1 << '\n' << un_reachable_cnt;
        return 0;
    }
}