首页 > 其他分享 >[JOISC 2014 Day3] 电压 题解

[JOISC 2014 Day3] 电压 题解

时间:2023-08-17 17:33:20浏览次数:39  
标签:std 返祖 题解 valueType Day3 iter JOISC depth odd

题面

给定 \(n\) 个点 \(m\) 条边的无向图。

现在要对每个点黑白染色。

若能够使一条边连接的两点颜色相同,其他边连接的两点颜色不同,则这条边合法。

求合法的边数。

$ 2 \leq n \leq 10^5,1 \leq m \leq 2 \times 10^5$。

图可能不连通,不保证没有重边。

题解

首先考虑转化一下题目条件,可以转化为删除一条边后剩余的边组成一个二分图,且该边连接的点在二分图的同一部。在此基础上经过分析可以得出偶环上的边均不合法,奇环上的边合法当且仅当其覆盖所有奇环。那么接下来的问题就转化成了统计每条边覆盖的偶环数和奇环数,以及整张图中的奇环数。

考虑环是如何产生的,发现在图的 DFS 生成树上每条返祖边均会产生环。所以考虑对于每条返祖边 \(\left(u, pa\right)\),设其连接的两点在 DFS 生成树上的深度差为 \(\Delta = \operatorname{depth}_x - \operatorname{depth}_{pa}\),那么环长显然为 \(len = \Delta + 1\)。所以这个返祖边覆盖的树边上都会覆盖一个对应的环,可以发现这个贡献是对一条链的贡献,故可以应用边差分解决。

接下来考虑如何统计答案,注意到统计的时候只会统计树边,也就是说返祖边不会被统计,下面讨论缺少的情况。

  • 如果图中只存在一个奇环,那么这条边会产生贡献,判断出这种情况计算即可;

  • 如果图中存在多于一个奇环,那么可以发现不存在一个返祖边存在于多个环中,也就是说返祖边一定不合法,不会产生贡献,故无需考虑。

Code

#include <bits/stdc++.h>

typedef int valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;
typedef std::vector<bool> bitset;

valueType N, M, oddCount = 0;
bitset visited;
ValueVector depth, even, odd;
ValueMatrix G;

void dfs(valueType x, valueType from) {
    visited[x] = true;

    depth[x] = depth[from] + 1;

    bool first = true;

    for (auto const &iter: G[x]) {
        if (first && iter == from) {
            first = false;

            continue;
        }

        if (!visited[iter]) {
            dfs(iter, x);

            odd[x] += odd[iter];
            even[x] += even[iter];
        } else if (depth[iter] < depth[x]) {
            valueType const delta = depth[x] - depth[iter] + 1;

            if (delta & 1) {
                ++odd[x];
                --odd[iter];
                ++oddCount;
            } else {
                ++even[x];
                --even[iter];
            }
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    std::cin >> N >> M;

    G.resize(N + 1);

    for (valueType i = 0; i < M; ++i) {
        valueType a, b;

        std::cin >> a >> b;

        G[a].emplace_back(b);
        G[b].emplace_back(a);
    }

    depth.resize(N + 1, 0);
    even.resize(N + 1, 0);
    odd.resize(N + 1, 0);
    visited.resize(N + 1, false);

    for (valueType i = 1; i <= N; ++i)
        if (!visited[i])
            dfs(i, 0);

    valueType ans = 0;

    for (valueType i = 1; i <= N; ++i)
        if (depth[i] != 1 && even[i] == 0 && odd[i] == oddCount)
            ++ans;

    if (oddCount == 1)
        ++ans;

    std::cout << ans << std::endl;
}

标签:std,返祖,题解,valueType,Day3,iter,JOISC,depth,odd
From: https://www.cnblogs.com/User-Unauthorized/p/solution-AT-JOISC2014-J.html

相关文章

  • javascript学习笔记day3
    今天没做啥笔记都是些学了的基础知识,学的都是像while,switch这些基础的语法,下面带是笔记++i前置运算和i++后置运算的区别:前置运行先相加再计算,后端运算先计算完再++。比较符也有隐式转换brank退出循环continue退出本次循环继续下次循环 顺便把while的循环作业一起放上来了,这个......
  • P3780 [SDOI2017] 苹果树 题解
    DescriptionP3780[SDOI2017]苹果树给定一棵\(n\)个点的树,每个点有若干个价值相同的苹果,儿子能摘至少一个仅当父亲被摘至少一个。给定\(k\),设\(h\)为你摘的苹果的最大深度,你做多能摘\(k+h\)个,求最大价值。对于所有数据,\(1\len\le5\times10^4\),\(1\lek\le5\time......
  • P4183 [USACO18JAN] Cow at Large P 题解
    题意分析我们首先想到,枚举贝茜在\(x\)点,枚举度数大于\(2\)的点为\(y\)。设\(x\)的度数为\(a\),\(y\)的度数为\(b\)。我们首先发现每个\(x\)点都有一个初始的贡献为\(a\)条通往叶子的路径。如果点\(y\)到最近的叶子节点的距离大于到\(x\)的点的距离(农夫不能在......
  • 安防监控视频汇聚平台EasyCVR视频平台调用iframe地址无法播放的问题解决方案
    安防监控视频汇聚平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、视频云存储、视频集中存储、视频存储磁盘阵列、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、AI算法中台智能分析无缝对接等功能。为了便于用户......
  • 安防监控视频汇聚平台EasyCVR视频平台调用iframe地址无法播放的问题解决方案
    安防监控视频汇聚平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、视频云存储、视频集中存储、视频存储磁盘阵列、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、AI算法中台智能分析无缝对接等功能。为了便于用户二......
  • vue项目在360浏览器兼容模式下SCRIPT1002: 语法错误以及“fetch”未定义问题解决
    使用360浏览器的兼容模式,vue项目页面空白,打开控制台,发现如下报错:SCRIPT1002:语法错误 解决方法如下:1、安装依赖npminstall--savecore-jsregenerator-runtime2、在main.js引入import'core-js/stable';import'regenerator-runtime/runtime';3、在babel.confi......
  • CF1545B题解
    CF1545B题解题目描述你有一个长为\(n\)的棋盘,这个棋盘上有一些棋子,你可以进行如下操作:如果第\(i+2\)个位置是空的,且第\(i+1\)个位置非空,则可以将第\(i\)个位置的棋子挪到第\(i+2\)个位置(\(i+2\leqn\)).如果第\(i-2\)个位置是空的,且第\(i-1......
  • arc136,arc137,arc138题解
    ARC136A-EAA↔BB贪心。可以把BB换成A,可以把BA换成AB。BTripleShift直观上觉得只要数集相同,那么就是可以变换的。大概方法就是每次找到正确的数把它挪到数列的端点,这样显然是可行的。但是在相反的三个上出现了问题,原因在于只剩最后两个数时方向可能是反着的。分析......
  • arc133,arc134,arc135题解
    ARC133A-EAErasebyValue扣掉一个数当且仅当这个数后面有更小的数。特判单增即可。BDividingSubsequence相对比较有启发性。发现有倍数关系的数对只有\(O(n\logn)\)对,于是可以把对应下标攒成一堆二元组,于是一个合法的取数方案就变成了两个维度分别严格上升的元素集合......
  • arc130,arc131,arc132题解
    ARC130A-DARemoveOneCharacter对每个连续块分别处理即可。BColorfulLines非常经典的题目,对于每一行每一列记录最后出现的颜色并计算贡献即可。CDigitSumMinimization有点细节。枚举最后两个数,显然加起来超过十是很好的;然后前面的数应该尽量凑九,然后要注意尽量不选......