Solution -「LOJ #3310」丁香之路

solution,loj,丁香,之路 · 浏览次数 : 10

小编点评

```cpp const int MN = 2.5e3; int n, m, s, fa[MN + 100], deg[MN + 100]; int find(int u) { while (u != fa[u]) u = fa[u] = fa[fa[u]]; return u;} bool unite(int u, int v) { if (find(u) != find(v)) {fa[find(u)] = find(v);return 1;} return 0;} int main(){ ios::sync_with_stdio(0); cin.tie(nullptr); cin >> n >> m >> s; s --; iota(fa, fa+n, 0); ll res = 0; rep(m) { int u, v;cin >> u >> v;u--;v--; deg[u] ++ , deg[v] ++; res += abs(u - v); unite(u, v); } vi tmp(fa, fa+n); rep(n) { deg[s] ++ , deg[i] ++; unite(s, i); vi id; rep(j,n) if (deg[j]%2) id.pb(j); ll sum = 0; rep(j,intsz(id)-1) { rep(k,id[j],id[j+1]) unite(k, k+1); sum += id[j+1]-id[j]; j++; } vi from, to; vi().swap(id); rep(j,n) if (deg[j] > 0) id.pb(j); rep(j,intsz(id)-1) from.pb(id[j]), to.pb(id[j+1]); vi(intsz(to)).swap(id); iota(id.begin(), id.end(), 0); sort(id.begin(), id.end(), [&](int x, int y) { return to[x]-from[x]<to[y]-from[y]; }); for (int j : id) { if (unite(from[j], to[j])) sum += 2*(to[j]-from[j]); } cout<< res + sum << \" \\"[i==n-1]; deg[s] -- , deg[i] --; rep(j,n) fa[j] = tmp[j]; }} /*急||速||地||下||坠||*/。归纳总结以上内容,生成内容时需要带简单的排版 ```

正文

  首先有两个前置技巧:1) 两点间的最短距离就是直接连接两点的边的长度;2) 遍历一个子图的最小花费是最小生成树的边权之和乘二。原问题让我们找出一条最短且必经过钦定边的 \(( s, i )\) 路径,那么我们先将 \(\lang s , i \rang\) 连上,问题就变成了找出一条最短且必经过钦定边 \(( s, i)\) 的回路。虽然每条边不一定恰好经过一次,但是对于正确性的判断,每个点的度数为偶数依然是一个必要条件,再加上连通性的限制,一条回路的正确性就可以由这两条必要条件充要表示。

  其次来考虑如何修复每个点度数的奇偶性,一个贪心策略是把一条 \((s, i)\) 拆成 \((s, s+1), (s+1, s+2) \dots (i-1, i)\),由于边权的性质,可以发现这样拆分一定不劣;又考虑连通性修复,类似以上。

const int MN = 2.5e3;
int n, m, s, fa[MN + 100], deg[MN + 100];
int find(int u) {
    while (u != fa[u]) u = fa[u] = fa[fa[u]];
    return u;
}
bool unite(int u, int v) {
    if (find(u) != find(v)) {fa[find(u)] = find(v);return 1;}
    return 0;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    cin >> n >> m >> s; s --;
    iota(fa, fa+n, 0);
    ll res = 0;
    rep(m) {
        int u, v;cin >> u >> v;u--;v--;
        deg[u] ++ , deg[v] ++;
        res += abs(u - v);
        unite(u, v);
    }
    vi tmp(fa, fa+n);
    rep(n) {
        deg[s] ++ , deg[i] ++;
        unite(s, i);
        vi id;
        rep(j,n) if (deg[j]%2) id.pb(j);
        ll sum = 0;
        rep(j,intsz(id)-1) {
            rep(k,id[j],id[j+1]) unite(k, k+1);
            sum += id[j+1]-id[j];
            j++;
        }
        vi from, to; vi().swap(id);
        rep(j,n) if (deg[j] > 0) id.pb(j);
        rep(j,intsz(id)-1) from.pb(id[j]), to.pb(id[j+1]);
        vi(intsz(to)).swap(id);
        iota(id.begin(), id.end(), 0);
        sort(id.begin(), id.end(), [&](int x, int y) {
            return to[x]-from[x]<to[y]-from[y];
        });
        for (int j : id) {
            if (unite(from[j], to[j])) sum += 2*(to[j]-from[j]);
        }
        cout<< res + sum << " \n"[i==n-1];
        deg[s] -- , deg[i] --;
        rep(j,n) fa[j] = tmp[j];
    }
}
/*
急
|
|
速
|
|
地
|
|
下
|
|
坠
|
|
*/

与Solution -「LOJ #3310」丁香之路相似的内容:

Solution -「LOJ #3310」丁香之路

首先有两个前置技巧:1) 两点间的最短距离就是直接连接两点的边的长度;2) 遍历一个子图的最小花费是最小生成树的边权之和乘二。原问题让我们找出一条最短且必经过钦定边的 \(( s, i )\) 路径,那么我们先将 \(\lang s , i \rang\) 连上,问题就变成了找出一条最短且必经过钦定

Solution -「HDU」Ridiculous Netizens

Desc. 给定一棵 \(N\) 个节点无根树,找出满足以下条件的集合 \(S\) 的数量: \(S \subseteq \{1,\dots,n\}\); \(S\) 的导出子图联通; \(\displaystyle\prod_{v \in S} a_v \leqslant M\)。 Sol. 点分

Solution -「模拟赛」草莓蛋糕

\(\max(a_x + a_y, b_y + b_x)\) 的贡献形式不是独立的,并不好进行分析。考虑通过分类讨论将 \(\max\) 拆开。若令 \(h_i = a_i - b_i\),\(h'_i = b_i - a_i\),可以发现若 \(h_x \geqslant h'_y\) 取值则为

Solution -「JOISC 2020」建筑装饰 4

朴素的 DP 形式是定义 \(f_{i, j, A/B}\) 表示前 \(i\) 个元素选择了 \(j\) 个 \(A\) 的可达性. \(\mathcal O(n^2)\). 交换状态与值域, 定义 \(f_{i, A/B, A/B}\) 表示前 \(i\) 个元素中的最后一个元素 (即 \(i\

Solution -「ARC 106E」Medals

Desc. Link. 你有 \(n\) 个朋友,他们会来你家玩,第 \(i\) 个人 \(1...A_i\) 天来玩,然后 \(A_i+1...2A_i\) 天不来,然后 \(2A_i+1...3A_i\) 又会来,以此类推; 每天你会选一个来玩的人,给他颁个奖,如果没人来玩,你就不颁奖。 你要给

MetaTown:一个可以自己构建数字资产的平台

摘要:华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案。 本文分享自华为云社区《基于MetaTown构建数字资产平台》,作者: 阿米托福。 华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案,由华为云数字资产链

带你了解基于Ploto构建自动驾驶平台

摘要:华为云Solution as Code推出基于Ploto构建自动驾驶平台解决方案。 本文分享自华为云社区《基于Ploto构建自动驾驶平台》,作者:阿米托福 。 2022年6月15日,主题为“因聚而生 为你所能”的华为伙伴暨开发者大会 2022 正式开启,在自动驾驶专场中,华为云携手合作伙伴联合

pbjs 无法编码 bytes 类型数据问题的解决方案

一段包含 bytes 类型的 protobuf 二进制数据,经过 pbjs 解码生成的 json 文件,再传递给 pbjs 编码后生成的二进制数据和原始数据差异巨大,经过一番探究,发现居然是 pbjs 的一个 bug,快来看看你是否踩过这个坑吧~