Cod sursa(job #1681948)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 9 aprilie 2016 20:48:30
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.81 kb
#include<cstdio>
#include<vector>
#include<algorithm>
const int dim=8192;
const int MAXN=310;
using namespace std;
int n,poz=0;
int dad[MAXN*MAXN],height[MAXN*MAXN];
char buff[dim];
struct cell{int l,c,cost;};
struct query{int x1,y1,x2,y2,position,answer;};
vector<cell> cells;
vector<query> queries,first,second;
bool cmp(cell a,cell b){
    if(a.cost>b.cost)
        return true;
    return false;
}
bool cmp0(query a,query b){
    if(a.position<b.position)
        return true;
    return false;
}
int number(int l,int c){
    return (l-1)*n+c;
}
void initialize(){
    int i;
    for(i=1;i<=n*n;i++){
        dad[i]=0;
        height[i]=0;
    }
}
int find_dad(int node){
    if(dad[node]==node)
        return node;
    return dad[node]=find_dad(dad[node]);
}
void join(int node1,int node2){
    int dad1=find_dad(node1),dad2=find_dad(node2);
    if(dad1==dad2)
        return;
    if(height[dad1]>height[dad2])
        dad[dad2]=dad1;
    else
        if(height[dad2]>height[dad1])
            dad[dad1]=dad2;
        else{
            dad[dad2]=dad1;
            height[dad1]++;
        }
}
int check(int l,int c){
    if(c<1||l<1||c>n||l>n)
        return 0;
    if(dad[number(l,c)]==0)
        return 0;
    return 1;
}
void add(int l,int c){
    int node=number(l,c);
    dad[node]=node;
    height[node]=1;
    if(check(l-1,c)==1)
        join(node,number(l-1,c));
    if(check(l+1,c)==1)
        join(node,number(l+1,c));
    if(check(l,c-1)==1)
        join(node,number(l,c-1));
    if(check(l,c+1)==1)
        join(node,number(l,c+1));
}
void unite(){
    int l1=first.size(),l2=second.size(),i=0,j=0;
    queries.clear();
    while(i<l1&&j<l2)
        if(first[i].answer>second[j].answer){
            queries.push_back(first[i]);
            i++;
        }
        else{
            queries.push_back(second[j]);
            j++;
        }
    while(i<l1){
        queries.push_back(first[i]);
        i++;
    }
    while(j<l2){
        queries.push_back(second[j]);
        j++;
    }
}
void read(int &numar){
    numar=0;
    while(buff[poz]<'0'||buff[poz]>'9'){
        poz++;
        if(poz==dim){
            fread(buff,1,dim,stdin);
            poz=0;
        }
    }
    while(buff[poz]>='0'&&buff[poz]<='9'){
        numar=numar*10+buff[poz]-'0';
        poz++;
        if(poz==dim){
            fread(buff,1,dim,stdin);
            poz=0;
        }
    }
}
int main(){
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);
    int m,i,q,a,b,c,bit,j,x,x1,y1,x2,y2,dad1,dad2;
    fread(buff,1,dim,stdin);
    read(n);
    read(q);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++){
            read(x);
            cells.push_back({i,j,x});
        }
    for(i=1;i<=q;i++){
        read(x1);
        read(y1);
        read(x2);
        read(y2);
        queries.push_back({x1,y1,x2,y2,i,0});
    }
    sort(cells.begin(),cells.end(),cmp);
    for(bit=29;bit>=0;bit--){
        initialize();
        first.clear();
        second.clear();
        j=0;
        for(i=0;i<q;i++){
            while(j<n*n&&cells[j].cost>=queries[i].answer+(1<<bit)){
                add(cells[j].l,cells[j].c);
                j++;
            }
            dad1=find_dad(number(queries[i].x1,queries[i].y1));
            dad2=find_dad(number(queries[i].x2,queries[i].y2));
            if(dad1!=0&&dad1==dad2){
                queries[i].answer+=(1<<bit);
                first.push_back(queries[i]);
            }
            else
                second.push_back(queries[i]);
        }
        unite();
    }
    sort(queries.begin(),queries.end(),cmp0);
    for(i=0;i<q;i++)
        if(queries[i].answer>0)
            printf("%d\n",queries[i].answer);
        else
            printf("-1\n");
    return 0;
}