Cod sursa(job #972081)

Utilizator dan_tudorDan Tudor dan_tudor Data 10 iulie 2013 22:36:06
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <string.h>
#include <set>

using namespace std;

ifstream cin("pirati.in");
ofstream cout("pirati.out");


const int MAXN = 1005;
const int oo = (1<<31)-1;
const int dx[]={1, 0, -1, 0, 1, -1, 1, -1};
const int dy[]={0, 1,  0,-1, 1, -1,-1,  1};
const int h = 200;


typedef set<int> Graph[MAXN*MAXN];
typedef set<int> :: iterator It;

int n, m, K, q, px, py, cx, cy, a[MAXN][MAXN], Lev[MAXN*MAXN], T2[MAXN*MAXN], T[MAXN*MAXN];
int RMQ[20][MAXN*MAXN>>2];
bitset <MAXN*MAXN> used;
char c;
bool viz[MAXN][MAXN];
Graph G;

void fill(int x, int y, int ex, int c)
{
    viz[x][y] = true;
    a[x][y] = c;
    for(int i = 0 ; i < 8 ; ++ i)
    {
        int xnou = x + dx[i];
        int ynou = y + dy[i];
        if(xnou >= 1 && xnou <= n && ynou >= 1 && ynou <= m )
            if(!viz[xnou][ynou] && a[xnou][ynou] == ex)
                fill(xnou, ynou, ex, c);
    }
}

void dfs(int nod, int n1, int lev, int father)
{
    Lev[nod] = lev;
    T2[nod] = n1;
    T[nod] = father;
    used[nod] = true;
    if(lev % h == 0) n1 = nod;

    for(It it = G[nod].begin(), fin = G[nod].end() ; it != fin ; ++ it)
        if(!used[*it])
            dfs(*it, n1, lev+1, nod);
}

int LCA(int x, int y)
{
    while(T2[x] != T2[y])
        if(Lev[x] > Lev[y])
            x = T2[x];
        else
            y = T2[y];

    while(x != y)
        if(Lev[x] > Lev[y])
            x = T[x];
        else
            y = T[y];

    return x;
}

int main()
{
    int nr = 0;
    cin >> n >> m >> q;
    for(int i = 1 ; i <= n ; ++ i)
        for(int j = 1 ; j <= m ; ++ j)
        {
            cin >> c;
            a[i][j] = c;
        }
    for(int i = 1 ; i <= n ; ++ i)
        for(int j = 1 ; j <= m ; ++ j)
            if(!viz[i][j])
            {
                fill(i, j, a[i][j],++nr);
            }
    for(int i = 1 ; i <= n ; ++ i)
        for(int j = 1 ; j <= m ; ++ j)
            for(int d = 0 ; d < 8 ; ++ d)
            {
                int xnou = i + dx[d];
                int ynou = j + dy[d];
                if(xnou >= 1 && xnou <= n && ynou >= 1 && ynou <= m)
                if(a[xnou][ynou] != a[i][j] && G[a[i][j]].find(a[xnou][ynou]) == G[a[i][j]].end())
                    G[a[i][j]].insert(a[xnou][ynou]),
                    G[a[xnou][ynou]].insert(a[i][j]);
            }

    dfs(1, 0, 0, 0);

    for(int i = 1 ; i <= q; ++ i)
    {
        int x, y, A, B;
        cin >> x >> y >> A >> B;
        int lca = LCA(a[x][y], a[A][B]);
        cout << (Lev[a[x][y]] - Lev[lca] + Lev[a[A][B]] - Lev[lca]) / 2 << "\n";
    }

    cin.close();
    cout.close();
    return 0;
}