洛谷7457 [CERC2018] The Bridge on the River Kawaii

题目大意

有一个 $n$ 个点的图,有 $q$ 个操作,每个操作形如:

$ \texttt{0 x y v:}$ 在 $x,y$ 间添加一条权值为 $v$ 的边。

$ \texttt{1 x y:}$ 删除 $x,y$ 之间的边,保证存在。

$ \texttt{2 x y:}$ 询问 $x,y$ 所有路径最大权值的最小值。

$ 1 \leq n, q \leq 2 \times 10 ^ 5, 1 \leq v \leq 10$

题目分析

我们先忽略这个 $v$ ,看看我们得到了什么:加入一条边,删除一条边,询问两点是否联通。

这让我们联想到什么?没错,动态图连通性

再一看,这个 $v$ 范围非常的小,于是我们考虑枚举 $v$ 的最大值,每次把权值不超过 $v$ 的边加入图中,询问两点之间是否联通。

这可以很轻松的使用线段树分治解决,时间复杂度 $ \Theta (vn \log^2 n) $ 。

代码

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
#include <bits/stdc++.h>

#define R register
#define ll long long
#define pair std::pair<int, int>
#define mp(i, j) std::make_pair(i, j)
#define meow(cat...) fprintf(stderr, cat)
#define sum(a, b, mod) (((a) + (b)) % mod)

const int MaxN = 2e5 + 10;
const int MaxM = 5e5 + 10;

struct Modify
{
int x, y;
} p[MaxM];

struct Operation
{
int op, x, y, v, id;
} op[MaxM];

struct Query
{
int x, y, t, id;
} q[MaxM], lq[MaxM], rq[MaxM];

std::vector<int> v[MaxM << 2];
int cnt, ans[MaxM], Ans[MaxM]; pair st[MaxM];
std::unordered_map<int, int> tim[MaxN];
int n, m, top, num, maxv, fa[MaxN], rk[MaxN];

int getf(int x)
{
if (x == fa[x])
return fa[x];
return getf(fa[x]);
}

void del(int cur)
{
while (top > cur)
{
pair pre = st[top--];
fa[pre.first] = pre.first;
rk[pre.first] = pre.second;
}
}

void merge(int x, int y)
{
x = getf(x), y = getf(y);
if (x == y) return;
if (rk[x] < rk[y]) std::swap(x, y);
fa[y] = x, st[++top] = mp(y, rk[y]);
if (rk[x] == rk[y])
st[++top] = mp(x, ++rk[x]);
}

void modify(int id, int l, int r, int ql, int qr, int pos)
{
if (ql <= l && r <= qr)
return (void)v[id].push_back(pos);
int mid = (l + r) >> 1;
if (ql <= mid) modify(id << 1, l, mid, ql, qr, pos);
if (qr > mid) modify(id << 1 | 1, mid + 1, r, ql, qr, pos);
}

inline int read()
{
int x = 0;
char ch = getchar();
while (ch > '9' || ch < '0')
ch = getchar();
while (ch <= '9' && ch >= '0')
x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return x;
}

void solve(int id, int l, int r, int st, int ed)
{
if(st > ed) return; int cur = top;
for(int i = 0; i < v[id].size(); i++)
merge(p[v[id][i]].x, p[v[id][i]].y);
if(l == r)
{
for(int i = st; i <= ed; i++)
ans[q[i].id] = (getf(q[i].x) == getf(q[i].y));
return;
}
int mid = (l + r) >> 1, lt = 0, rt = 0;
for(int i = st; i <= ed; i++)
if(q[i].t <= mid) lq[++lt] = q[i];
else rq[++rt] = q[i];
for(int i = 1; i <= lt; i++) q[st + i - 1] = lq[i];
for(int i = 1; i <= rt; i++) q[st + i + lt - 1] = rq[i];
solve(id << 1, l, mid, st, st + lt - 1);
solve(id << 1 | 1, mid + 1, r, st + lt, ed), del(cur);
}

int main()
{
n = read(), m = read(), memset(Ans, -1, sizeof(Ans));
for(int i = 1; i <= m; i++)
{
op[i].op = read(), op[i].x = read() + 1, op[i].y = read() + 1, op[i].id = i;
if(op[i].op == 0) op[i].v = read(), maxv = std::max(maxv, op[i].v);
if(op[i].x > op[i].y) std::swap(op[i].x, op[i].y);
}
for(int V = 0; V <= maxv; V++)
{
for(int i = 1; i <= n; i++)
tim[i].clear(); cnt = num = top = 0;
for(int i = 1; i <= n; i++) fa[i] = i, rk[i] = 1;
for(int i = 1; i <= m * 4; i++) v[i].clear();
for(int i = 1; i <= m; i++)
{
int x = op[i].x, y = op[i].y;
if(op[i].op == 0 && op[i].v <= V) tim[x][y] = i;
else if (op[i].op == 1 && tim[x][y])
{
modify(1, 1, m, tim[x][y], i, ++cnt);
p[cnt] = (Modify) {x, y}, tim[x][y] = 0;
}
else if(op[i].op == 2) q[++num] = (Query) {x, y, i, num};
}
for(int i = 1; i <= n; i++)
for(auto x : tim[i])
if(x.second)
{
modify(1, 1, m, x.second, m, ++cnt);
p[cnt] = (Modify) {i, x.first};
}
solve(1, 1, m, 1, num);
for(int i = 1; i <= num; i++)
{
if(ans[i] && Ans[i] == -1)
Ans[i] = V;
ans[i] = 0;
}
}
for(int i = 1; i <= num; i++)
printf("%d\n", Ans[i]);
return 0;
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×