Cod sursa(job #2764852)

Utilizator Vlad_AnicaAnica-Popa Vlad-Ioan Vlad_Anica Data 22 iulie 2021 21:36:53
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.61 kb
#include <queue>
#include <vector>
#include <iostream>
#include <stdio.h>

using namespace std;
const int NMAX = 15000, LOGNMAX = 13;

struct edge
{
    int v1, v2, w;
};
bool operator < (const edge& x, const edge& y)
{return x.w > y.w;}

struct dirEdge
{
    int v, w;
};

int euler[2 * NMAX - 1], h[2 * NMAX - 1], wes[2 * NMAX - 2], log2[2 * NMAX - 1];
int spTblH[2 * NMAX - 1][LOGNMAX + 1], spTblW[2 * NMAX - 1][LOGNMAX + 1];
int ind;
bool vis[NMAX];
vector<dirEdge> lists[NMAX];
vector<dirEdge> apmEdges[NMAX];
vector<int> pos[NMAX];
priority_queue<edge> myHeap;

void initApm(int n);
void initLog2();
void buildEuler(int node, int currH);
void initSptbls(int n);
int queryHeight(int lo, int hi);
int queryWeight(int lo, int hi);
int getLCA(int v1, int v2);
int getMax(int v1, int v2);

int main()
{
    int n, m, k, i, v1, v2;
    edge e;
    FILE *fin = fopen("radiatie.in", "r");
    fscanf(fin, "%d%d%d", &n, &m, &k);
    for (i = 0; i < m; i++)
    {
        fscanf(fin, "%d%d%d", &e.v1, &e.v2, &e.w);
        lists[e.v1 - 1].push_back({e.v2 - 1, e.w});
        lists[e.v2 - 1].push_back({e.v1 - 1, e.w});
    }

    initApm(n);
    buildEuler(0, 0);
    initLog2();
    initSptbls(n * 2 - 1);

    FILE *fout = fopen("radiatie.out", "w");

    for (i = 0; i < k; i++)
    {
        fscanf(fin, "%d%d", &v1, &v2);
        fprintf(fout, "%d\n", getMax(v1 - 1, v2 - 1));
    }


    fclose(fin);
    fclose(fout);
    return 0;
}

void initApm(int n)
{
    int i, len, cpn;
    edge e;
    vis[0] = 1;
    len = lists[0].size();
    for (i = 0; i < len; i++)
        myHeap.push({0, lists[0][i].v, lists[0][i].w});

    cpn = n;
    n--;
    while (n)
    {
        e = myHeap.top();
        myHeap.pop();
        if (!vis[e.v2])
        {
            vis[e.v2] = 1;
            n--;
            apmEdges[e.v1].push_back({e.v2, e.w});
            apmEdges[e.v2].push_back({e.v1, e.w});
            len = lists[e.v2].size();
            for (i = 0; i < len; i++)
                myHeap.push({e.v2, lists[e.v2][i].v, lists[e.v2][i].w});
        }
    }
    for (i = 0; i < cpn; i++)
        vis[i] = 0;

    myHeap = priority_queue<edge>();


}
void initLog2()
{
    int logi = -1;
    for (int i = 1; i < (NMAX << 1); i++)
    {
        if (1 << (logi + 1) == i)
            logi++;
        log2[i] = logi;
    }
}
void buildEuler(int node, int currH)
{
    int len = apmEdges[node].size();
    vis[node] = 1;
    for (int i = 0; i < len; i++)
    {
        if (!vis[apmEdges[node][i].v])
        {
            h[ind] = currH;
            wes[ind] = apmEdges[node][i].w;
            euler[ind] = node;
            pos[node].push_back(ind);
            ind++;
            buildEuler(apmEdges[node][i].v, currH + 1);

        }
    }
    h[ind] = currH;
    wes[ind] = 0;
    euler[ind] = node;
    pos[node].push_back(ind);
    ind++;
}
void initSptbls(int n)
{
    for (int i = 0; i < n; i++)
        spTblH[i][0] = i;
    for (int i = 1; i <= log2[n]; i++)
    {
        int pow2 = 1 << i, smPow2 = pow2 >> 1;
        for (int j = 0; j + pow2 - 1 < n; j++)
            if (h[spTblH[j][i - 1]] < h[spTblH[j + smPow2][i - 1]])
                spTblH[j][i] = spTblH[j][i - 1];
            else
                spTblH[j][i] = spTblH[j + smPow2][i - 1];
    }

    n--;
    for (int i = 0; i < n; i++)
        spTblW[i][0] = wes[i];
    for (int i = 1; i <= log2[n]; i++)
    {
        int pow2 = 1 << i, smPow2 = pow2 >> 1;
        for (int j = 0; j  + pow2 - 1 < n; j++)
            spTblW[j][i] = max(spTblW[j][i - 1], spTblW[j + smPow2][i - 1]);
    }
}
int queryHeight(int lo, int hi)
{
    int len = hi - lo + 1;
    if (h[spTblH[lo][log2[len]]] < h[spTblH[hi - (1 << log2[len]) + 1][log2[len]]])
        return spTblH[lo][log2[len]];
    return spTblH[hi - (1 << log2[len]) + 1][log2[len]];

}
int queryWeight(int lo, int hi)
{
    int len = hi - lo + 1;
    return max(spTblW[lo][log2[len]], spTblW[hi - (1 << log2[len]) + 1][log2[len]]);
}
int getLCA(int v1, int v2)
{
    return euler[queryHeight(pos[v1][0], pos[v2][0])];
}
int getMax(int v1, int v2)
{
    int lca = getLCA(v1, v2), i, maxx = 0;
    if (lca != v1)
    {
        i = -1;
        while (pos[lca][i + 1] <= pos[v1][0])
            i++;
        maxx = max(maxx, queryWeight(pos[lca][i], pos[v1][0] - 1));
    }
    if (lca != v2)
    {
        i = -1;
        while (pos[lca][i + 1] < pos[v2][0])
            i++;
        maxx = max(maxx, queryWeight(pos[lca][i], pos[v2][0] - 1));
    }
    return maxx;
}