2020-2021 ICPC NERC (NEERC), North-Western Russia Regional Contest (Northern Subregionals) E(离散化+欧拉回路)

E - Easy Compare-and-Set

题意

给定n个条件,如果存在一个合法序列使得这n个判断条件成立,则输出Yes和这个合法序列,否则输出No。

分析

首先可以发现对于wi=0的操作我们可以在处理完wi=1的操作之后讨论一下即可。
发现aibi很大需要对其进行离散化操作。离散化后可以将aibi看成点,即一条从a走向b的有向边。将所有的wi=1的边连接起来之后,则可以发现题目等价于问以c为起点能否恰好经过每条边一次,最后跑一边欧拉回路记录路径即可。
对于wi=0的情况我们可以先将所有aic的操作先用掉,对于ai=c的操作在跑图时插在第2的点中间即可。
最后注意判断无解情况,具体看代码实现。

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, c;
    std::cin >> n >> c;
    std::unordered_map<int, int> mp;
    std::vector<int> w(n);
    std::vector<std::array<int, 3>> edges(n);
    int cur = 0;
    mp[c] = cur++;
    c = mp[c];
    for (int i = 0; i < n; ++i) {
        int a, b;
        std::cin >> a >> b >> w[i];
        if (!mp.count(a)) mp[a] = cur++;
        if (!mp.count(b)) mp[b] = cur++;
        a = mp[a], b = mp[b];
        edges[i] = {a, b, w[i]};
    }
    std::vector<int> din(cur), dout(cur);
    std::vector<std::vector<std::pair<int, int>>> g(cur);
    std::set<int> dot;
    for (int i = 0; i < n; ++i) {
        auto [a, b, e] = edges[i];
        if (e == 1) {
            g[a].emplace_back(b, i);
            dot.emplace(a), dot.emplace(b);
            din[b] += 1, dout[a] += 1;
        }
    }
    for (int num = 0; auto x : dot) if (din[x] != dout[x]) {
        if (din[x] < dout[x]) {
            if (x != c || dout[x] - din[x] > 1) {
                std::cout << "No" << '\n';
                return 0;
            }
        } else {
            num += 1;
            if (num > 1 || din[x] - dout[x] > 1) {
                std::cout << "No" << '\n';
                return 0;
            }
        }
    }
    std::vector<bool> use(n);    
    std::vector<int> path, ans1, ans2;
    for (int i = 0; i < n; ++i) {
        auto [a, b, _] = edges[i];
        if (w[i] == 0 && a != c) {
            use[i] = true;
            ans1.emplace_back(i);
        } else if (w[i] == 0) {
            use[i] = true;
            ans2.emplace_back(i);
        }
    }
    auto dfs = [&](auto &&self, int u) ->void {
        while(size(g[u])) {
            auto [v, e] = g[u].rbegin()[0];
            use[e] = true;
            g[u].pop_back();
            self(self, v);
            path.emplace_back(e);
        }
    };
    dfs(dfs, c);
    if (((int)size(path) == 0 && size(ans2)) || std::count(use.begin(), use.end(), true) != n || (cur == 1 && std::count(w.begin(), w.end(), 1) != n)) {
        std::cout << "No" << '\n';
    } else {
        std::cout << "Yes" << '\n';
        for (int i = 0; i < (int)size(ans1); ++i) {
            std::cout << ans1[i] + 1 << " ";
        }
        int pos = size(path);
        for (int i = 0; i < (int)size(path); ++i) { 
            if (edges[path.rbegin()[i]][0] == c) {
                std::cout << path.rbegin()[i] + 1 << " \n"[i == (int)size(path) - 1];
            } else {
                pos = i;
                break;
            }
        }
        for (int i = 0; i < (int)size(ans2); ++i) {
            std::cout << ans2[i] + 1 << " ";
        }
        for (int i = pos; i < (int)size(path); ++i) {
            std::cout << path.rbegin()[i] + 1 << " \n"[i == (int)size(path) - 1];
        }
    }
}

最后感谢学弟提供的hack样例,不然实在是没想到为什么wa6。
╲(。◕‿◕。)╱

posted @   sleeeeeping  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
  1. 1 吹梦到西洲 恋恋故人难,黄诗扶,妖扬
  2. 2 敢归云间宿 三无Marblue
吹梦到西洲 - 恋恋故人难,黄诗扶,妖扬
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 颀鞍

作曲 : 铃木航海

编曲 : 远藤直弥/冯帆

制作人 : 冯帆/铃木航海

(妖扬)

(妖扬)

无何化有 感物知春秋

秋毫濡沫欲绸缪 搦管相留

(黄诗扶)

留骨攒峰 留容映水秀

留观四时曾邂逅 佳人西洲

(妖扬)

(妖扬)

西洲何有 远树平高丘

云闲方外雨不收 稚子牵牛

(黄诗扶)

闹市无声 百态阴晴栩栩侔

藤衣半卷苔衣皱 岁月自无忧

(妖扬)

(妖扬)

驾马驱车 尚几程扶摇入画中 咫尺

(黄诗扶)

径曲桥横 精诚难通

(黄诗扶、妖扬)

(黄诗扶、妖扬)

盼你渡口 待你桥头

松香接地走

挥癯龙绣虎出怀袖

起微石落海连波动

描数曲箜篌线同轴

勒笔烟直大漠 沧浪盘虬

一纸淋漓漫点方圆透

记我 长风万里绕指未相勾

形生意成 此意 逍遥不游

(妖扬)

(妖扬)

日月何寿 江海滴更漏

爱向人间借朝暮 悲喜为酬

(黄诗扶)

种柳春莺 知它风尘不可救

绵绵更在三生后 谁隔世读关鸠

(妖扬)

(妖扬)

诗说红豆 遍南国未见人长久 见多少

(黄诗扶)

来时芳华 去时白头

(黄诗扶、妖扬)

(黄诗扶、妖扬)

忘你不舍 寻你不休

画外人易朽

似浓淡相间色相构

染冰雪先披琉璃胄

蘸朱紫将登金银楼

天命碧城灰土 刀弓褐锈

举手夜古泼断青蓝右

照我 萤灯嫁昼只影归洪流

身魂如寄 此世 逍遥不游

(黄诗扶)

(黄诗扶)

情一物 无木成林无水行舟

情一事 未算藏谋真还谬

情一人 积深不厚积年不旧

情一念 墨尽非空 百代飞白骤 划地为囚

(妖扬)

(妖扬)

蓝田需汲酒 惟琼浆能浇美玉瘦

至高者清难垢 至贵者润因愁

痴竭火 知她不能求

醉逢歌 知他不必候

只约灵犀过隙灵光暗相投

(黄诗扶、妖扬)

(黄诗扶、妖扬)

万籁停吹奏

支颐听秋水问蜉蝣

既玄冥不可量北斗

却何信相思最温柔

顾盼花发鸿蒙 怦然而梦

你与二十八宿皆回眸

系我 彩翼鲸尾红丝天地周

情之所至 此心 逍遥不游

吉他 : ShadOw

钢琴 : ShadOw

和声编写 : 冯帆

和声 : 黄诗扶

人声混音 : 徐志明

混音 : 冯帆

母带 : 冯帆

企划 : 三糙文化

出品公司 : Negia Entertainment Inc.

点击右上角即可分享
微信分享提示