Submission #146346

# Submission time Handle Problem Language Result Execution time Memory
146346 2019-08-23T14:31:15 Z jacynkaa Traffic (CEOI11_tra) C++14
100 / 100
1574 ms 96044 KB
#include <bits/stdc++.h>
#include <math.h>
#include <chrono>
using namespace std;
#pragma GCC optimize("-O3")
#define endl "\n"
#define mp make_pair
#define st first
#define nd second
#define pii pair<int, int>
#define pb push_back
#define _upgrade ios_base::sync_with_stdio(0), cout.setf(ios::fixed), cout.precision(10) //cin.tie(0); cout.tie(0);
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FWD(i, a, b) for (int i = (a); i < (b); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define fwd(i, a, b) for (int i = (a); i < (b); ++i)
#define all(c) (c).begin(), (c).end()
#define what(x) cerr << #x << " is " << x << endl;

struct SilnieSpojne
{
    static const int MMM = 1e6 + 100; //zmienic jezeli potrzeba
    int n;
    vector<vector<int>> G, GT, Gspojne; //graf, graf z odwroconymi krawedziami, graf na spojnych
    vector<vector<int>> sklad;          //sklad kazdej ze spojnych
    vector<int> doKtorej;               // do kotrej spojnej nalezy wierzcholek
    bitset<MMM> odwiedzone;             //pomocnicze
    stack<int> kolejnosc;

    void dfs1(int x)
    {
        odwiedzone[x] = true;
        for (int y : G[x])
            if (!odwiedzone[y])
                dfs1(y);
        kolejnosc.push(x);
    }

    void dfs2(int x, int ktoraSpojna)
    {
        doKtorej[x] = ktoraSpojna;
        sklad[ktoraSpojna].pb(x);
        for (int y : GT[x])
            if (doKtorej[y] == -1)
                dfs2(y, ktoraSpojna);
    }

    inline int ileSpojnych()
    {
        return Gspojne.size();
    }

    void ini(vector<vector<int>> &G) //zakladamy numeracje wierzcholkow od 0, choc dla 1 tez (chyba) dziala
    {
        this->G = G;
        n = G.size();
        GT.resize(n);
        doKtorej.resize(n, -1);
        rep(i, n) for (int a : G[i]) GT[a].push_back(i); //tworzenie odwroconego grafu

        rep(i, n) if (!odwiedzone[i]) dfs1(i);
        while (!kolejnosc.empty())
        {
            int x = kolejnosc.top();
            kolejnosc.pop();
            if (doKtorej[x] == -1)
            {
                sklad.pb(vector<int>());
                dfs2(x, sklad.size() - 1);
            }
        }

        Gspojne.resize(sklad.size());
        vector<int> P(ileSpojnych(), -1);                                                                            //pomocniczy zaznaczamy czy juz mamy krawedz do danej spojnej
        rep(i, ileSpojnych()) for (int x : sklad[i]) for (int y : G[x]) if (doKtorej[y] != i && P[doKtorej[y]] != i) //dorzucam krawedzi do grafu
        {
            Gspojne[i].pb(doKtorej[y]);
            P[doKtorej[y]] = i;
        }
    }
    void debug()
    {
        cerr << "SKLADY SPOJNYCH:" << endl;
        rep(i, ileSpojnych())
        {
            auto A = sklad[i];
            cerr << "sklad " << i << " to: ";
            for (auto b : A)
                cerr << b + 1 << " ";
            cerr << endl;
        }
        cerr << "GRAF NA SPOJNYCH:" << endl;
        rep(i, ileSpojnych())
        {
            cerr << "sasiedzi wierzchołka " << i << ": ";
            for (auto b : Gspojne[i])
                cerr << b << " ";
            cerr << endl;
        }
    }
};

const int MAXN = 4e5;
int A, B, n, m;
vector<vector<int>> G;
pii punkty[MAXN];
pii val[MAXN];
vector<int> koncowe, poczatkowe; //posortowane po gorze
bitset<MAXN> visited;
SilnieSpojne S;

void wczytywanie()
{
    cin >> n >> m >> A >> B;
    G.resize(n);
    rep(i, n) cin >> punkty[i].st >> punkty[i].nd;

    rep(i, m)
    {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        G[a].pb(b);
        if (c == 2)
            G[b].pb(a);
    }
}

void dfs1(int x)
{
    visited[x] = true;
    for (int y : G[x])
        if (!visited[y])
            dfs1(y);
}

void pre()
{
    rep(i, n) if (punkty[i].st == 0) poczatkowe.pb(i);
    for (int x : poczatkowe)
        if (!visited[x])
            dfs1(x);

    rep(i, n) if (punkty[i].st == A && visited[i]) koncowe.pb(i);

    sort(all(poczatkowe), [](int a, int b) { return punkty[a].nd > punkty[b].nd; });
    sort(all(koncowe), [](int a, int b) { return punkty[a].nd > punkty[b].nd; });
    S.ini(G);

    fill(val, val + MAXN, mp(MAXN, -MAXN)); //UWAGA
}

void merge(pii &A, pii B)
{
    A = mp(min(A.st, B.st), max(A.nd, B.nd));
}

void dfs2(int x)
{
    visited[x] = true;
    for (int y : S.Gspojne[x])
        if (!visited[y])
            dfs2(y);
    for (int y : S.Gspojne[x])
        merge(val[x], val[y]);
}

void solve()
{
    rep(i, koncowe.size())
        merge(val[S.doKtorej[koncowe[i]]], {i, i});
    //rep(i, S.ileSpojnych()) cerr << "wartosc wierzcholka : " << i << " to: " << val[i].st << " " << val[i].nd << endl;
    visited.reset();
    rep(i, S.ileSpojnych()) dfs2(i);

    for (int a : poczatkowe)
        cout << max(0, val[S.doKtorej[a]].nd - val[S.doKtorej[a]].st + 1) << endl;
}

void debug()
{
    S.debug();
    cerr << "POCZATKOWE" << endl;
    for (int a : poczatkowe)
        cout << a + 1 << " ";
    cout << endl;
    cerr << "KONCOWE" << endl;
    for (int a : koncowe)
        cout << a + 1 << " ";
    cout << endl;

    rep(i, S.ileSpojnych()) cerr << "wartosc wierzcholka : " << i << " to: " << val[i].st << " " << val[i].nd << endl;
}

main()
{
    _upgrade;
    wczytywanie();
    pre();
    solve();
    //debug();
}

Compilation message

tra.cpp: In function 'void solve()':
tra.cpp:15:37: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define rep(i, n) for (int i = 0; i < (n); ++i)
                                     ^
tra.cpp:171:5: note: in expansion of macro 'rep'
     rep(i, koncowe.size())
     ^~~
tra.cpp: At global scope:
tra.cpp:196:6: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
 main()
      ^
# Verdict Execution time Memory Grader output
1 Correct 5 ms 3704 KB Output is correct
2 Correct 5 ms 3576 KB Output is correct
3 Correct 5 ms 3620 KB Output is correct
4 Correct 4 ms 3576 KB Output is correct
5 Correct 5 ms 3560 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 5 ms 3576 KB Output is correct
2 Correct 5 ms 3704 KB Output is correct
3 Correct 5 ms 3704 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 5 ms 3704 KB Output is correct
2 Correct 6 ms 3832 KB Output is correct
3 Correct 5 ms 3832 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 4472 KB Output is correct
2 Correct 12 ms 4984 KB Output is correct
3 Correct 11 ms 4600 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 34 ms 11180 KB Output is correct
2 Correct 94 ms 16456 KB Output is correct
3 Correct 63 ms 10928 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 76 ms 14104 KB Output is correct
2 Correct 128 ms 19352 KB Output is correct
3 Correct 98 ms 18732 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 174 ms 25904 KB Output is correct
2 Correct 239 ms 35548 KB Output is correct
3 Correct 302 ms 29236 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 275 ms 24344 KB Output is correct
2 Correct 289 ms 29460 KB Output is correct
3 Correct 304 ms 29660 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 389 ms 42256 KB Output is correct
2 Correct 452 ms 61512 KB Output is correct
3 Correct 683 ms 53564 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 719 ms 69404 KB Output is correct
2 Correct 829 ms 91648 KB Output is correct
3 Correct 736 ms 63120 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1216 ms 63088 KB Output is correct
2 Correct 843 ms 93736 KB Output is correct
3 Correct 1476 ms 82300 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 396 ms 63940 KB Output is correct
2 Correct 925 ms 96044 KB Output is correct
3 Correct 1271 ms 84020 KB Output is correct
4 Correct 1574 ms 86992 KB Output is correct