2020-2021 ICPC NERC (NEERC), North-Western Russia Regional Contest (Northern Subregionals) E(离散化+欧拉回路)
E - Easy Compare-and-Set
题意
给定n个条件,如果存在一个合法序列使得这n个判断条件成立,则输出Yes和这个合法序列,否则输出No。
分析
首先可以发现对于
发现
对于
最后注意判断无解情况,具体看代码实现。
代码实现
#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。
╲(。◕‿◕。)╱
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理