Submission #1400923

#TimeUsernameProblemLanguageResultExecution timeMemory
1400923michael_hOne-Way Streets (CEOI17_oneway)C++17
0 / 100
4 ms8772 KiB
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
const int lim = 1e5 + 5;
int n,m, low[lim], disc[lim], visited[lim], timer = 0, p2[50];
int bridge[lim], tree_code[lim], parent[50][lim], depth[lim], save[lim];
vector <pair <int,int>> path[lim], tree[lim], rtree[lim];
pair <int,int> pathing[lim];
char ans[lim];

void dfs(int pos, int id)
{
    low[pos] = disc[pos] = timer;
    timer++;
    for(auto [i,code] : path[pos])
    {
        if(code == id)
            continue;

        if(visited[i])
        {
            low[pos] = min(low[pos], disc[i]);
        }
        else
        {
            visited[i] = true;
            dfs(i, code);
            low[pos] = min(low[i], low[pos]);
            if(low[i] > disc[pos])
            {
                bridge[code] = true;
            }
        }
    }
    return;
}

void dfs2(int pos, int par)
{
    visited[pos] = true;
    for(auto [i, code] : tree[pos])
    {
        if(i != par)
        {
            rtree[pos].push_back({i, code});
            parent[0][i] = pos;
            dfs2(i,pos);
        }
    }
    return;
}

void compute_depth(int pos, int curr_depth)
{
    depth[pos] = curr_depth;
    for(auto [i,code] : rtree[pos])
    {
        compute_depth(i,curr_depth + 1);
    }
    return;
}

void precomputation(int pos)
{
    for(int i = 1 ; i <= 30 ; i++)
    {
        parent[i][pos] = parent[i - 1][parent[i - 1][pos]];
    }
    for(auto [i,code] : rtree[pos])
        precomputation(i);
    return;
}

pair <int, int> dist_lca(int a, int b)
{
    int ans1 = 0, ans2 = 0;
    for(int x = 30 ; x >= 0 ; x--)
    {
        if(depth[a] - depth[b] >= p2[x])
        {
            ans1 += p2[x];
            a = parent[x][a];
        }

        if(depth[b] - depth[a] >= p2[x])
        {
            ans2 += p2[x];
            b = parent[x][b];
        }
    }

    //depth sudah sama
    if(a == b)
        return {ans1, ans2};

    for(int x = 30 ; x >= 0 ; x--)
    {
        if(parent[x][a] != parent[x][b])
        {
            a = parent[x][a], b = parent[x][b];
            ans1 += p2[x], ans2 += p2[x];
        }
    }

    if(parent[0][a] == parent[0][b])
        return {ans1 + 1, ans2 + 1};
    return {-1,-1};
}


int dfsfin(int pos)
{
    int coded = save[pos];
    for(auto [i, id] : rtree[pos])
    {
        int val = dfsfin(i);
        auto [u,v] = pathing[id];
        if(val < 0)
        {
            //turun
            val++;
            coded = min(coded,val);
            if(u == pos && v == i)
                ans[id] = 'R';
            else
                ans[id] = 'L';
        }
        else if(val > 0)
        {
            //naik
            val--;
            coded = max(coded,val);
            if(u == pos && v == i)
                ans[id] = 'L';
            else
                ans[id] = 'R';
        }
    }

    //if(coded > 0) coded--;
    //else coded++;
    return coded;
}


int main()
{
    memset(save,0,sizeof(save));
    p2[0] = 1;
    for(int i = 1 ; i <= 30 ; i++)
        p2[i] = p2[i - 1]*2;
    scanf("%d %d", &n, &m);
    memset(visited,0,sizeof(visited));
    for(int i = 1 ; i <= m ; i++)
    {
        int a,b;
        scanf("%d %d", &a, &b);
        path[a].push_back({b,i});
        path[b].push_back({a,i});
        pathing[i] = {a,b};
    }

    for(int i = 1 ; i <= n ; i++)
    {
        if(!visited[i])
            dfs(i,-1);
    }

    int tree_id = 1;
    memset(tree_code,-1,sizeof(tree_code));
    for(int i = 1 ; i <= n ; i++)
    {
        if(tree_code[i] == -1)
        {
            queue <int> que;
            que.push(i);
            while(!que.empty())
            {
                int pos = que.front();
                que.pop();
                if(tree_code[pos] == -1)
                {
                    tree_code[pos] = tree_id;
                    for(auto [i, code] : path[pos])
                    {
                        if(bridge[code])
                        {
                            tree[tree_id].push_back({i, code});
                        }
                        else
                            que.push(i);
                    }
                }
            }
            tree_id++;
        }
    }

    /*
    printf("DEBUG Bridge:\n");
    for(int i = 1 ; i <= m ; i++)
        printf("%d -> %d\n", i, bridge[i]);

    printf("DEBUG Tree Code:\n");
    for(int i = 1 ; i <= n ; i++)
        printf("%d ", tree_code[i]);
    printf("\n");
    */

    for(int i = 1 ; i <= n ; i++)
    {
        for(int j = 0 ; j < tree[i].size() ; j++)
            tree[i][j].first = tree_code[tree[i][j].first];
    }

    memset(visited,0,sizeof(visited));
    for(int i = 1 ; i <= n ; i++)
    {
        if(!visited[i])
        {
            dfs2(i,-1);
            compute_depth(i,0);
            precomputation(i);
        }
    }

    int q;
    scanf("%d", &q);
    for(int i = 1 ; i <= q ; i++)
    {
        int a,b;
        scanf("%d %d", &a, &b);
        a = tree_code[a], b = tree_code[b];
        pair <int,int> val = dist_lca(a, b);

        //printf("mark %d %d -> %d %d\n", a,b, val.first, val.second);

        save[a] = max(save[a], val.first);
        save[b] = min(save[b], -1*val.second);
    }


    memset(visited,0,sizeof(visited));
    for(int i = 1 ; i <= n ; i++)
    {
        if(!visited[i])
            dfsfin(i);
    }

    for(int i = 1 ; i <= m ; i++)
    {
        if(ans[i] != 'L' && ans[i] != 'R')
            ans[i] = 'B';
        printf("%c", ans[i]);
    }
    printf("\n");
}

Compilation message (stderr)

oneway.cpp: In function 'int main()':
oneway.cpp:155:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  155 |     scanf("%d %d", &n, &m);
      |     ~~~~~^~~~~~~~~~~~~~~~~
oneway.cpp:160:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  160 |         scanf("%d %d", &a, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~
oneway.cpp:231:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  231 |     scanf("%d", &q);
      |     ~~~~~^~~~~~~~~~
oneway.cpp:235:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  235 |         scanf("%d %d", &a, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...