首页 > 其他分享 >Solution -「COCI 2009-2010」「洛谷 P8076」RESTORAN

Solution -「COCI 2009-2010」「洛谷 P8076」RESTORAN

时间:2022-12-23 22:55:24浏览次数:72  
标签:RESTORAN head 洛谷 int graph Solution vis clr deg

\(\mathscr{Description}\)

  Link.

  给定一个含 \(n\) 个点 \(m\) 条边的简单图, 求一种边二染色方案, 使得所有 \(\deg\ge2\) 的结点都邻接于两种颜色的边.

  \(n,m\le10^5\).

\(\mathscr{Solution}\)

  清甜味儿的题目比较调剂愚钝的大脑. (

  染色, 一开始的思路是匹配或网络流相关, 不过一看数据范围就大概弃了.

  第一个 motivation 大概也来自数据范围: 近线性做法 \(\to\) 生成树 (DFS 树) 上构造?

  很快, 我们发现树上的 "奇偶染色" (细节见最后一段描述) 是很强大的, 有且仅有树根有可能不合法. 树根在什么情况下合法呢? 简单讨论发现, 我们要求树根在一个偶环里. 可见, 无脑奇偶染色导致了一个挺严的限制因素, 这样的条件显得太奢侈啦!

  怎么办呢? 第二个 motivation 是: 保留一条特定的边, 它不在奇偶染色的考虑范围, 仅用于保证树根合法.

  保留了一条边, 树根倒是一定合法; 这条边的另一端又称了问题. 什么样的点忽略一条邻接边仍然能在奇偶染色下合法?

  其实所有 \(\deg\ge3\) 点都可以.

  因此, 我们的算法为: 找到一个 \(\deg\ge3\) 的点 \(u\), 保留其一条邻接边 \((u,v)\), 在连通块剩余边上从 \(v\) 出发 DFS, 树上奇偶染色, 返祖边和对应点子边同色. 染色完成后, 通过 \((u,v)\) 保证 \(v\) 的合法性. 此外需要特殊处理偶环. 当且仅当存在一个连通块为奇环时无解. 复杂度 \(\mathcal O(n+m)\).

\(\mathscr{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)

const int MAXN = 1e5;
int n, m, ecnt = 1, head[MAXN + 5], deg[MAXN + 5], clr[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
bool vis[MAXN + 5];

inline void link(const int u, const int v) {
    graph[++ecnt] = { v, head[u] }, head[u] = ecnt;
    graph[++ecnt] = { u, head[v] }, head[v] = ecnt;
}

inline void paint(const int u, const int cur) {
    vis[u] = true;
    for (int i = head[u], v; i; i = graph[i].nxt) {
        if (!clr[i >> 1] && !vis[v = graph[i].to]) {
            // printf("%d->%d\n", u, v);
            clr[i >> 1] = cur, paint(v, cur ^ 3);
        } else if (!clr[i >> 1]) {
            clr[i >> 1] = cur;
        }
    }
}

inline int count(const int u) {
    int ret = 1; vis[u] = true;
    for (int i = head[u], v; i; i = graph[i].nxt) {
        if (!vis[v = graph[i].to]) {
            ret += count(v);
        }
    }
    return ret;
}

int main() {
    scanf("%d %d", &n, &m);
    rep (i, 1, m) {
        int u, v; scanf("%d %d", &u, &v);
        ++deg[u], ++deg[v], link(u, v);
    }

    rep (u, 1, n) if (!vis[u]) {
        if (deg[u] == 1) paint(u, 1);
        else if (deg[u] > 2) {
            int v = graph[head[u]].to;
            clr[head[u] >> 1] = 1, paint(v, 2);
            if (!vis[u]) paint(u, 2);
        }
    }

    rep (u, 1, n) if (!vis[u] && deg[u] == 2) {
        if (count(u) & 1) return puts("0"), 0;
        for (int v = u, las = 0, cur = 1; ;) {
            for (int i = head[v], w; i; i = graph[i].nxt) {
                if ((w = graph[i].to) != las) {
                    clr[i >> 1] = cur, cur ^= 3, las = v, v = w;
                    break;
                }
            }
            if (v == u) break;
        }
    }

    rep (i, 1, m) printf("%d\n", clr[i]);
    return 0;
}

标签:RESTORAN,head,洛谷,int,graph,Solution,vis,clr,deg
From: https://www.cnblogs.com/rainybunny/p/17001792.html

相关文章

  • AcWing341. 洛谷P1073, NOIP2009 最优贸易
    AcWing题目传送门洛谷题目传送门题目大意\(~~~~~~\)一个投机倒把的奸商想要通过城市不太健全的贸易系统坑点钱,任意城市都可以买入或者卖出水晶球,他想尽量在便宜的城市买......
  • 洛谷 P2679 [NOIP2015 提高组]子串
    \(70pts\):记\(sub_A(i)\)表示\(A\)的前\(i\)个字符构成的子串,相应地,\(sub_B(i)\)为\(B\)的前\(i\)个字符构成的子串。设\(f(i,j,k)\)表示在\(sub_A(i......
  • 洛谷P2680 运输计划(LCA + 二分 + 树上边差分)
    洛谷P2680运输计划​ 现在有一棵树,每条树边上都有正权值。接下来,有m个询问,每次询问给出两个结点,这两个结点之间有一条路径。现在你可以任选一条树边,将其边权置为0,请输......
  • 洛谷 P5401 [CTS 2019] 珍珠 题解
    题目链接令\(c_i\)表示第i种颜色的珍珠的数量,显然我们最多能装的瓶数是\(\sum\lfloor\frac{c_i}2\rfloor\)。也就是说,\(c_i\)为奇数的\(i\)的数量不能太多,这个数量要......
  • Wallys/Qualcomm IPQ5018 solution application wifi6 , support M.2 Card Slot for Q
    IPQ5018,802.11ax,wifi6e,QCN9074,2X22.4Gsupport2xWiFi6ECardsupportBT5.1/Dual-coreARM64bitA53@1.0GHzProcessor512MBDDRL3LSystemMemory4MBNORFlash,......
  • The Solution of Porsche Piwis 2 software is stuck when running
    PorschePiwistesterII​Piwis2DiagnostictoolwithCF30LaptopV18.150PiwisTesterIIisprofessionaltesterforPorshe,themostpowefuldiagnoseandoffli......
  • 洛谷 P6580 [Ynoi 2019] 美好的每一天~ 不连续的存在 题解
    既然是YNOI那肯定是要分块的。先考虑树是一条链的情况,可以直接回滚莫队,对n个节点组成的序列分块。在回滚莫队的过程中,当前维护的区间一共会扩展\(O(n\sqrtn)\)次,每次都是......
  • 洛谷 P1712 [NOI2016] 区间
    很多套路糅合在一起的一道题。记\(len_i=r_i-l_i\)。则所求转化为一个有\(m\)个区间的集合\(S\),满足:存在一个\(x\),使得对于所有\(S\)中的区间\(i\),有\(l_......
  • 洛谷P3224 [HNOI2012]永无乡 题解 splay tree 启发式合并
    题目链接:https://www.luogu.com.cn/problem/P3224主要知识点是:树上启发式合并,即每次合并将小的树里面的每个点合并大大的树里面,时间复杂度\(O(n\log^2n)\)。同时需要......
  • 洛谷-P1450 硬币购物
    P1450硬币购物容斥||\(dp\)+单调队列优化容易看出是个多重背包,然后拿单调队列优化一下后,计算量为\(O(4ns)\)这种做法的话就是单调队列优化板子题#include<bits/......