uva : https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3145

 

espa에서는 괜찮은데 uva에서 제출해봤는데 TLE가 뜬다..

아무래도 소스가 lct나 splay를 쓰지않은 탐색코드이고 espa의 tc가 uva보다 약하기 때문인 것 같은데

lct ? splay를 공부해서 제출해봐야겠다.

 

지금 소스는 espa에서는 빠르게 통과되는 코드로

type2, 3번의 시간을 최대한 단축시키기 위해서

height 높이 개념을 이용했다.

 

LCA를 알면 좀더 빠르게 해결할 수 있다는데 뭐 통과는 되니까 일단 올려놓고

고급 자료구조를 공부한 후에 다시 적용해봐야겠다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <set>
#include <cmath>
#include <limits>
#include <cstring>
#include <string>
using namespace std;
 
struct NODE {
    int root = -1;
    int pn = -1;
    int pn_color = -1;
    int height = -1;
    struct pii {
        int num;
        int color;
    };
    vector<pii> other;
}node[50001];
 
bool visit[50001];
bool color_arr[31];
int inn, inm;
int join = 0;
int answer_edge, answer_color;
 
int check_tree(int x) {
    answer_edge++;
    if (color_arr[node[x].pn_color] == false) {
        answer_color++;
        color_arr[node[x].pn_color] = true;
    }
 
    return node[x].pn;
}
 
void make_height2(int x, int y) {
    memset(color_arr, 0sizeof(color_arr));
    while (node[x].height != node[y].height) {
        if (node[x].height > node[y].height) x = check_tree(x);
        else y = check_tree(y);
    }
    if (x != y) {
        while (x != y) {
            x = check_tree(x);
            y = check_tree(y);
        }
    }
}
 
int color_change(int x, int c) {
    for (int i = 0; i < node[node[x].pn].other.size(); i++) {
        if (node[node[x].pn].other[i].num == x) {
            node[node[x].pn].other[i].color = c;
            break;
        }
    }
    node[x].pn_color = c;
    return node[x].pn;
}
 
void make_height(int x, int y, int c) {
    while (node[x].height != node[y].height) {
        if (node[x].height > node[y].height) x = color_change(x, c);
        else y = color_change(y, c);
    }
 
    if (x != y) {
        while (x != y) {
            x = color_change(x, c);
            y = color_change(y, c);
        }
    }
}
 
void delete_node(int x, int y) {
    for (int i = 0; i < node[x].other.size(); i++) {
        if (node[x].other[i].num == y) {
            node[x].other.erase(node[x].other.begin() + i, node[x].other.begin() + i + 1);
            break;
        }
    }
}
 
void change_father(int x, int y, int c) {
    if (node[x].root != x)    delete_node(node[x].pn, x);
 
    node[y].other.push_back({ x, c });
    node[x].pn_color = c;
 
    queue<pair<pair<int,int>,int> > q;
    q.push({ {x,y},node[y].height });
 
    while (!q.empty()) {
        int temp = q.front().first.first;
        int p = q.front().first.second;
        int h = q.front().second;
        q.pop();
 
        node[temp].root = node[y].root;
        node[temp].pn = p;
        node[temp].height = h + 1;
        for (int i = 0; i < node[temp].other.size(); i++) {
            q.push({{ node[temp].other[i].num, temp}, h+1});
        }
    }
}
 
bool check_father(int x, int y) {
    if (x == y) return true;
    if (node[x].root == x) return false;
    return check_father(node[x].pn, y);
}
 
void insert_node(int num, int parent, int color) {
    if (parent == 0) { // root
        visit[num] = true;
        node[num].height = 0;
        node[num].pn = num;
        node[num].root = num;
        join++;
        return;
    }
 
    if (node[parent].root == -1return;
    if (visit[num]) {
        join++;
        return;
    }
 
    visit[num] = true;
    node[num].root = node[parent].root;
    node[num].pn = parent;
    node[num].pn_color = color;
    node[num].height = node[parent].height + 1;
    node[parent].other.push_back({ num, color });
    join++;
}
 
int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
 
    vector<pair<pair<intint>int> > in;
    cin >> inn >> inm;
 
    for (int i = 1; i <= inn; i++) {
        int num;
        cin >> num;
        in.push_back({ {num,0},i });
    }
    for (int i = 0; i < inn; i++) {
        int col;
        cin >> col;
        in[i].first.second = col;
    }
    sort(in.begin(), in.end());
 
    while (join != inn) {
        join = 0;
        for (int i = 0; i < inn; i++)
            insert_node(in[i].second, in[i].first.first, in[i].first.second);
    }
    for (int i = 1; i <= inn; i++) visit[i] = 0;
 
    while (inm--) {
        int type, x, y, c;
        cin >> type >> x >> y;
        if (type == 1) {
            cin >> c;
            if (x == y) continue;
            if (node[x].root != node[y].root) change_father(x, y, c);
            else {
                if (!check_father(y, x)) change_father(x, y, c);
            }
        }
        if (type == 2) {
            cin >> c;
            if (x == y || node[x].root != node[y].root) continue;
            make_height(x, y, c);
        }
        if (type == 3) {
            if (x == y || node[x].root != node[y].root)
                cout << "0 0\n";
            else {
                answer_edge = answer_color = 0;
                make_height2(x, y);
                cout << answer_edge << " " << answer_color << "\n";
            }
        }
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > uva' 카테고리의 다른 글

uva 10205번 stack 'em up  (0) 2020.04.27
uva 384번 Slurpys, BOJ 14906번 스러피  (0) 2020.03.31
uva 10150번 Doublets  (0) 2020.03.27
uva 10469번 To Carry or not to Carry  (0) 2020.03.23
uva 10010번 Where's Waldorf?  (0) 2020.03.23

+ Recent posts