Codeforces题解集
Posted hs-zlq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces题解集相关的知识,希望对你有一定的参考价值。
由于以后打算都用markdown写, 所以新开了一个帖子.
题意: 给出一个N(N (leq) 2e5)个点的无向图, 已知其中有k(2 (leq) k (leq) N)个点是"特殊的"的, 你必须选择其中两个点连边, 使得点1到点N的距离最大化.
思路: 问题转化为最大化 min(d[1][u] + 1 + d[v][n], d[1][v] + 1 + d[u][n]). 按d[1][u] - d[u][n]降序排列, 此时在选定当前点 i 后, 另一个点 j (j > i)无论是哪个, 最小值都是d[1][i] + 1 + d[j][n], 利用这一点, 就可以O(1)地查询后缀解决.
view code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++)
#define pii pair<int, int>
#define fi first
#define se second
#define pb push_back
int n, m, k;
const int maxv = 2e5 + 5;
const int inf = 0x3f3f3f3f;
int V, d[maxv];
vector<int> g[maxv];
pii p[maxv];
int suffix[maxv];
void solve(int s) {
queue<int> que;
que.push(s);
memset(d, 63, sizeof(d));
d[s] = 0;
while (!que.empty()) {
int q = que.front();
que.pop();
for (int i = 0; i < g[q].size(); i++) {
if (d[g[q][i]] == inf) {
d[g[q][i]] = d[q] + 1;
que.push(g[q][i]);
}
}
}
}
bool cmp(const pii &p1, const pii &p2) { return p1.fi - p1.se < p2.fi - p2.se; }
int sp[maxv], u, v;
int main() {
cin >> n >> m >> k;
inc(i, 0, k - 1) cin >> sp[i];
inc(i, 1, m) {
u--, v--;
cin >> u >> v;
g[u].pb(v);
g[v].pb(u);
}
solve(1);
for (int i = 0; i < k; i++) p[i].fi = d[sp[i]];
solve(n);
for (int i = 0; i < k; i++) p[i].se = d[sp[i]];
sort(p, p + k, cmp);
suffix[k - 1] = p[k - 1].se;
for (int i = k - 2; i >= 0; i--) suffix[i] = max(suffix[i + 1], p[i].se);
int res = 0;
for (int i = 0; i < k - 1; i++) res = max(res, p[i].fi + suffix[i + 1] + 1);
cout << min(d[1], res);
}
以上是关于Codeforces题解集的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 1630 E Making It Bipartite 题解 (Dilworth定理)
Codeforces 1012A Photo of The Sky
Codeforces 200A Cinema 并查集 + 思维 (看题解)
Codeforces 827D Best Edge Weight 倍增 + 并查集 || 倍增 + 压倍增标记 (看题解)