#include "simurgh.h"
#include <bits/stdc++.h>
using namespace std;
struct unionFind{
int par[502];
void init(int n){
for(int i=0; i<n; i++) par[i] = i;
}
int find(int x){
if(par[x] == x) return x;
return par[x] = find(par[x]);
}
void merge(int x, int y){
x = find(x), y = find(y);
par[y] = x;
}
};
struct Edge{
int s, e, idx;
Edge(){}
Edge(int s, int e, int idx): s(s), e(e), idx(idx){}
};
struct Comparison{
int a, b, v; /// ans[a] - ans[b] = v
Comparison(){}
Comparison(int a, int b, int v): a(a), b(b), v(v){}
bool operator<(const Comparison &r)const{
return abs(v) > abs(r.v);
}
};
int n, m;
vector<Edge> link[150002];
int edgeIdx[502][502];
int ex[150002], ey[150002];
bool ans[150002];
void oneTree();
void everyEdge();
vector<int> find_roads(int N, vector<int> u, std::vector<int> v) {
n = N, m = (int)u.size();
for(int i=0; i<n; i++) for(int j=0; j<n; j++) edgeIdx[i][j] = -1;
for(int i=0; i<m; i++){
link[u[i]].push_back(Edge(u[i], v[i], i));
link[v[i]].push_back(Edge(v[i], u[i], i));
ex[i] = u[i], ey[i] = v[i];
edgeIdx[ex[i]][ey[i]] = i;
edgeIdx[ey[i]][ex[i]] = i;
}
oneTree();
everyEdge();
vector<int> ret;
for(int i=0; i<m; i++) if(ans[i]) ret.push_back(i);
return ret;
}
vector<Edge> treeLink[150002];
vector<int> treeEdges;
bool inTree[150002];
int depth[150002], par[150002], LCADB[502][10];
bool checked[150002];
void dfs_tree(int x, int p){
par[x] = p;
for(Edge y: treeLink[x]){
if(y.e == p) continue;
depth[y.e] = depth[x] + 1;
dfs_tree(y.e, x);
}
}
int getLCA(int x, int y){
if(depth[x] > depth[y]) swap(x, y);
for(int d=9; d>=0; d--) if((depth[y] - depth[x]) & (1<<d)) y = LCADB[y][d];
if(x==y) return x;
for(int d=9; d>=0; d--) if(LCADB[x][d] != LCADB[y][d]) x = LCADB[x][d], y = LCADB[y][d];
return par[x];
}
void apply(int x, int t){
if(checked[x] && ans[x] != t) exit(1);
checked[x] = 1, ans[x] = t;
}
void oneTree(){
/// 아무 트리나 만들기
unionFind dsu;
dsu.init(n);
for(int i=0; i<m; i++){
if(dsu.find(ex[i]) != dsu.find(ey[i])){
dsu.merge(ex[i], ey[i]);
inTree[i] = 1;
treeLink[ex[i]].push_back(Edge(ex[i], ey[i], i));
treeLink[ey[i]].push_back(Edge(ey[i], ex[i], i));
treeEdges.push_back(i);
}
}
int treeSum = count_common_roads(treeEdges);
/// 트리를 탐색하기
dfs_tree(0, -1);
for(int i=0; i<n; i++) LCADB[i][0] = par[i];
for(int d=1; d<10; d++) for(int i=0; i<n; i++) LCADB[i][d] = (LCADB[i][d-1] == -1 ? -1 : LCADB[LCADB[i][d-1]][d-1]);
/// 각 간선이 포함되는지 확인하기
vector<Comparison> compare;
for(int edge: treeEdges){
int u = ex[edge], v = ey[edge];
if(depth[u] > depth[v]) swap(u, v);
/// 위로 가는 간선이 있는지 보자
int up = -1;
for(int i=0; i<m; i++){
if(inTree[i]) continue;
if((getLCA(v, ex[i]) == v) == (getLCA(v, ey[i]) == v)) continue;
up = i;
break;
}
if(up == -1){
checked[edge] = 1;
ans[edge] = 1;
continue;
}
/// 쿼리를 날려 확인해 보자
vector<int> qv1 = treeEdges;
qv1.erase(find(qv1.begin(), qv1.end(), edge));
qv1.push_back(up);
int qa1 = count_common_roads(qv1);
compare.push_back(Comparison(edge, up, treeSum - qa1));
/// 이제 쿼리를 하나 더 날리자
int top = getLCA(ex[up], ey[up]);
int highest;
if(top == ex[up]){
if(v != ey[up]) highest = edgeIdx[ey[up]][par[ey[up]]];
else highest = edgeIdx[par[ey[up]]][par[par[ey[up]]]];
}
else if(top == ey[up]){
if(v != ex[up]) highest = edgeIdx[ex[up]][par[ex[up]]];
else highest = edgeIdx[par[ex[up]]][par[par[ex[up]]]];
}
else if(v != ex[up]) highest = edgeIdx[ex[up]][par[ex[up]]];
else if(v != ey[up]) highest = edgeIdx[ey[up]][par[ey[up]]];
else exit(1);
vector<int> qv2 = qv1;
qv2.erase(find(qv2.begin(), qv2.end(), highest));
qv2.push_back(edge);
int qa2 = count_common_roads(qv2);
compare.push_back(Comparison(highest, edge, qa1 - qa2));
}
/// 비교 데이터를 바탕으로 결정하자.
sort(compare.begin(), compare.end());
for(Comparison com: compare){
if(com.v){
if(com.v == 1) apply(com.a, 1), apply(com.b, 0);
else apply(com.b, 1), apply(com.a, 0);
}
else if(checked[com.a] || checked[com.b]){
assert(!checked[com.a] || !checked[com.b] || ans[com.a] == ans[com.b]);
int result = ans[com.a] || ans[com.b];
apply(com.a, result), apply(com.b, result);
}
}
for(int edge: treeEdges){
if(!checked[edge]) apply(edge, 0);
}
}
int dnc(vector<int> &edgeList, int value = -1){
if(edgeList.empty()) return 0;
if(value == -1){
vector<int> qv;
unionFind dsu;
dsu.init(n);
for(auto x: edgeList){
qv.push_back(x);
dsu.merge(ex[x], ey[x]);
}
int base = 0;
for(auto x: treeEdges){
if(dsu.find(ex[x]) == dsu.find(ey[x])) continue;
base += ans[x];
qv.push_back(x);
dsu.merge(ex[x], ey[x]);
}
value = count_common_roads(qv) - base;
}
if(!value) return value;
if((int)edgeList.size() == 1){
apply(edgeList[0], 1);
return value;
}
vector<int> list1, list2;
int m = (int)edgeList.size() / 2;
for(int i=0; i<(int)edgeList.size(); i++){
if(i < m) list1.push_back(edgeList[i]);
else list2.push_back(edgeList[i]);
}
int tmp = value - dnc(list1);
dnc(list2, tmp);
return value;
}
void everyEdge(){
for(int i=0; i<n; i++){
/// 정점 i 주변의 간선들을 찾을 것이다.
vector<int> searchTo;
for(Edge e: link[i]) if(!inTree[e.idx]) searchTo.push_back(e.idx);
dnc(searchTo);
}
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
7380 KB |
correct |
2 |
Correct |
4 ms |
7380 KB |
correct |
3 |
Correct |
4 ms |
7380 KB |
correct |
4 |
Correct |
4 ms |
7380 KB |
correct |
5 |
Correct |
4 ms |
7380 KB |
correct |
6 |
Correct |
4 ms |
7400 KB |
correct |
7 |
Correct |
5 ms |
7380 KB |
correct |
8 |
Correct |
4 ms |
7380 KB |
correct |
9 |
Correct |
5 ms |
7320 KB |
correct |
10 |
Correct |
4 ms |
7380 KB |
correct |
11 |
Correct |
4 ms |
7380 KB |
correct |
12 |
Correct |
4 ms |
7396 KB |
correct |
13 |
Correct |
4 ms |
7380 KB |
correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
7380 KB |
correct |
2 |
Correct |
4 ms |
7380 KB |
correct |
3 |
Correct |
4 ms |
7380 KB |
correct |
4 |
Correct |
4 ms |
7380 KB |
correct |
5 |
Correct |
4 ms |
7380 KB |
correct |
6 |
Correct |
4 ms |
7400 KB |
correct |
7 |
Correct |
5 ms |
7380 KB |
correct |
8 |
Correct |
4 ms |
7380 KB |
correct |
9 |
Correct |
5 ms |
7320 KB |
correct |
10 |
Correct |
4 ms |
7380 KB |
correct |
11 |
Correct |
4 ms |
7380 KB |
correct |
12 |
Correct |
4 ms |
7396 KB |
correct |
13 |
Correct |
4 ms |
7380 KB |
correct |
14 |
Correct |
6 ms |
7508 KB |
correct |
15 |
Correct |
5 ms |
7508 KB |
correct |
16 |
Correct |
6 ms |
7508 KB |
correct |
17 |
Correct |
7 ms |
7508 KB |
correct |
18 |
Correct |
6 ms |
7508 KB |
correct |
19 |
Correct |
6 ms |
7508 KB |
correct |
20 |
Correct |
5 ms |
7508 KB |
correct |
21 |
Correct |
6 ms |
7508 KB |
correct |
22 |
Correct |
4 ms |
7508 KB |
correct |
23 |
Correct |
4 ms |
7508 KB |
correct |
24 |
Correct |
5 ms |
7508 KB |
correct |
25 |
Correct |
5 ms |
7380 KB |
correct |
26 |
Correct |
5 ms |
7508 KB |
correct |
27 |
Correct |
5 ms |
7508 KB |
correct |
28 |
Correct |
5 ms |
7508 KB |
correct |
29 |
Correct |
5 ms |
7380 KB |
correct |
30 |
Correct |
4 ms |
7508 KB |
correct |
31 |
Correct |
4 ms |
7508 KB |
correct |
32 |
Correct |
4 ms |
7508 KB |
correct |
33 |
Correct |
4 ms |
7508 KB |
correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
7380 KB |
correct |
2 |
Correct |
4 ms |
7380 KB |
correct |
3 |
Correct |
4 ms |
7380 KB |
correct |
4 |
Correct |
4 ms |
7380 KB |
correct |
5 |
Correct |
4 ms |
7380 KB |
correct |
6 |
Correct |
4 ms |
7400 KB |
correct |
7 |
Correct |
5 ms |
7380 KB |
correct |
8 |
Correct |
4 ms |
7380 KB |
correct |
9 |
Correct |
5 ms |
7320 KB |
correct |
10 |
Correct |
4 ms |
7380 KB |
correct |
11 |
Correct |
4 ms |
7380 KB |
correct |
12 |
Correct |
4 ms |
7396 KB |
correct |
13 |
Correct |
4 ms |
7380 KB |
correct |
14 |
Correct |
6 ms |
7508 KB |
correct |
15 |
Correct |
5 ms |
7508 KB |
correct |
16 |
Correct |
6 ms |
7508 KB |
correct |
17 |
Correct |
7 ms |
7508 KB |
correct |
18 |
Correct |
6 ms |
7508 KB |
correct |
19 |
Correct |
6 ms |
7508 KB |
correct |
20 |
Correct |
5 ms |
7508 KB |
correct |
21 |
Correct |
6 ms |
7508 KB |
correct |
22 |
Correct |
4 ms |
7508 KB |
correct |
23 |
Correct |
4 ms |
7508 KB |
correct |
24 |
Correct |
5 ms |
7508 KB |
correct |
25 |
Correct |
5 ms |
7380 KB |
correct |
26 |
Correct |
5 ms |
7508 KB |
correct |
27 |
Correct |
5 ms |
7508 KB |
correct |
28 |
Correct |
5 ms |
7508 KB |
correct |
29 |
Correct |
5 ms |
7380 KB |
correct |
30 |
Correct |
4 ms |
7508 KB |
correct |
31 |
Correct |
4 ms |
7508 KB |
correct |
32 |
Correct |
4 ms |
7508 KB |
correct |
33 |
Correct |
4 ms |
7508 KB |
correct |
34 |
Correct |
66 ms |
9480 KB |
correct |
35 |
Correct |
63 ms |
9420 KB |
correct |
36 |
Correct |
63 ms |
9216 KB |
correct |
37 |
Correct |
23 ms |
7892 KB |
correct |
38 |
Correct |
70 ms |
9368 KB |
correct |
39 |
Correct |
57 ms |
9300 KB |
correct |
40 |
Correct |
55 ms |
9220 KB |
correct |
41 |
Correct |
52 ms |
9380 KB |
correct |
42 |
Correct |
54 ms |
9380 KB |
correct |
43 |
Correct |
18 ms |
8916 KB |
correct |
44 |
Correct |
21 ms |
8592 KB |
correct |
45 |
Correct |
17 ms |
8628 KB |
correct |
46 |
Correct |
17 ms |
8448 KB |
correct |
47 |
Correct |
15 ms |
8148 KB |
correct |
48 |
Correct |
10 ms |
7916 KB |
correct |
49 |
Correct |
14 ms |
7892 KB |
correct |
50 |
Correct |
15 ms |
8148 KB |
correct |
51 |
Correct |
21 ms |
8572 KB |
correct |
52 |
Correct |
20 ms |
8532 KB |
correct |
53 |
Correct |
19 ms |
8456 KB |
correct |
54 |
Correct |
18 ms |
8916 KB |
correct |
55 |
Correct |
15 ms |
8532 KB |
correct |
56 |
Correct |
16 ms |
8624 KB |
correct |
57 |
Correct |
18 ms |
8660 KB |
correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
7380 KB |
correct |
2 |
Correct |
4 ms |
7380 KB |
correct |
3 |
Correct |
211 ms |
12996 KB |
correct |
4 |
Correct |
339 ms |
15940 KB |
correct |
5 |
Correct |
335 ms |
15904 KB |
correct |
6 |
Correct |
250 ms |
15912 KB |
correct |
7 |
Correct |
238 ms |
15880 KB |
correct |
8 |
Correct |
248 ms |
16000 KB |
correct |
9 |
Correct |
311 ms |
16032 KB |
correct |
10 |
Correct |
328 ms |
15816 KB |
correct |
11 |
Correct |
330 ms |
15940 KB |
correct |
12 |
Correct |
319 ms |
15928 KB |
correct |
13 |
Correct |
5 ms |
7380 KB |
correct |
14 |
Correct |
296 ms |
15908 KB |
correct |
15 |
Correct |
329 ms |
15924 KB |
correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
7380 KB |
correct |
2 |
Correct |
4 ms |
7380 KB |
correct |
3 |
Correct |
4 ms |
7380 KB |
correct |
4 |
Correct |
4 ms |
7380 KB |
correct |
5 |
Correct |
4 ms |
7380 KB |
correct |
6 |
Correct |
4 ms |
7400 KB |
correct |
7 |
Correct |
5 ms |
7380 KB |
correct |
8 |
Correct |
4 ms |
7380 KB |
correct |
9 |
Correct |
5 ms |
7320 KB |
correct |
10 |
Correct |
4 ms |
7380 KB |
correct |
11 |
Correct |
4 ms |
7380 KB |
correct |
12 |
Correct |
4 ms |
7396 KB |
correct |
13 |
Correct |
4 ms |
7380 KB |
correct |
14 |
Correct |
6 ms |
7508 KB |
correct |
15 |
Correct |
5 ms |
7508 KB |
correct |
16 |
Correct |
6 ms |
7508 KB |
correct |
17 |
Correct |
7 ms |
7508 KB |
correct |
18 |
Correct |
6 ms |
7508 KB |
correct |
19 |
Correct |
6 ms |
7508 KB |
correct |
20 |
Correct |
5 ms |
7508 KB |
correct |
21 |
Correct |
6 ms |
7508 KB |
correct |
22 |
Correct |
4 ms |
7508 KB |
correct |
23 |
Correct |
4 ms |
7508 KB |
correct |
24 |
Correct |
5 ms |
7508 KB |
correct |
25 |
Correct |
5 ms |
7380 KB |
correct |
26 |
Correct |
5 ms |
7508 KB |
correct |
27 |
Correct |
5 ms |
7508 KB |
correct |
28 |
Correct |
5 ms |
7508 KB |
correct |
29 |
Correct |
5 ms |
7380 KB |
correct |
30 |
Correct |
4 ms |
7508 KB |
correct |
31 |
Correct |
4 ms |
7508 KB |
correct |
32 |
Correct |
4 ms |
7508 KB |
correct |
33 |
Correct |
4 ms |
7508 KB |
correct |
34 |
Correct |
66 ms |
9480 KB |
correct |
35 |
Correct |
63 ms |
9420 KB |
correct |
36 |
Correct |
63 ms |
9216 KB |
correct |
37 |
Correct |
23 ms |
7892 KB |
correct |
38 |
Correct |
70 ms |
9368 KB |
correct |
39 |
Correct |
57 ms |
9300 KB |
correct |
40 |
Correct |
55 ms |
9220 KB |
correct |
41 |
Correct |
52 ms |
9380 KB |
correct |
42 |
Correct |
54 ms |
9380 KB |
correct |
43 |
Correct |
18 ms |
8916 KB |
correct |
44 |
Correct |
21 ms |
8592 KB |
correct |
45 |
Correct |
17 ms |
8628 KB |
correct |
46 |
Correct |
17 ms |
8448 KB |
correct |
47 |
Correct |
15 ms |
8148 KB |
correct |
48 |
Correct |
10 ms |
7916 KB |
correct |
49 |
Correct |
14 ms |
7892 KB |
correct |
50 |
Correct |
15 ms |
8148 KB |
correct |
51 |
Correct |
21 ms |
8572 KB |
correct |
52 |
Correct |
20 ms |
8532 KB |
correct |
53 |
Correct |
19 ms |
8456 KB |
correct |
54 |
Correct |
18 ms |
8916 KB |
correct |
55 |
Correct |
15 ms |
8532 KB |
correct |
56 |
Correct |
16 ms |
8624 KB |
correct |
57 |
Correct |
18 ms |
8660 KB |
correct |
58 |
Correct |
5 ms |
7380 KB |
correct |
59 |
Correct |
4 ms |
7380 KB |
correct |
60 |
Correct |
211 ms |
12996 KB |
correct |
61 |
Correct |
339 ms |
15940 KB |
correct |
62 |
Correct |
335 ms |
15904 KB |
correct |
63 |
Correct |
250 ms |
15912 KB |
correct |
64 |
Correct |
238 ms |
15880 KB |
correct |
65 |
Correct |
248 ms |
16000 KB |
correct |
66 |
Correct |
311 ms |
16032 KB |
correct |
67 |
Correct |
328 ms |
15816 KB |
correct |
68 |
Correct |
330 ms |
15940 KB |
correct |
69 |
Correct |
319 ms |
15928 KB |
correct |
70 |
Correct |
5 ms |
7380 KB |
correct |
71 |
Correct |
296 ms |
15908 KB |
correct |
72 |
Correct |
329 ms |
15924 KB |
correct |
73 |
Correct |
5 ms |
7360 KB |
correct |
74 |
Incorrect |
275 ms |
15752 KB |
WA in grader: NO |
75 |
Halted |
0 ms |
0 KB |
- |