惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
S
Securelist
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
Attack and Defense Labs
Attack and Defense Labs
Vercel News
Vercel News
腾讯CDC
Google DeepMind News
Google DeepMind News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
量子位
S
Schneier on Security
Hacker News: Ask HN
Hacker News: Ask HN
Cyberwarzone
Cyberwarzone
S
Security Affairs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
T
Tenable Blog
PCI Perspectives
PCI Perspectives
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
W
WeLiveSecurity
N
News | PayPal Newsroom
P
Proofpoint News Feed
O
OpenAI News
C
CERT Recently Published Vulnerability Notes
B
Blog
Cisco Talos Blog
Cisco Talos Blog
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy

PYM博客

Python 部署 Lexfence:基于 AI 大模型的内容审核系统 Docker 部署 Lexfence:一款开源易用的AI审核服务 2026年了,电脑病毒真是防不胜防,3个好用的杀毒软件推荐(亲身经历) 本站已更换 Cloudflare 至 EdgeOne Claude Opus 4.8来了!不再是比聪明,而是更能干活,敢于认错,变得诚实了! Note.ms在线简洁匿名记事本,如何修改/0页面 解禁了?RTX 5090 PRO6000上架京东自营店 用工具轻松的给Frpc配置SSL证书,穿透Http与Https流量,开启强制Https跳转 「POJ1740」A New Stone Game SG函数与博弈论题解 Deepseek V4发布了!综合能力比肩顶级闭源模型! 国内就可以使用的免费SuperGrok,无需登录无需排队,完全公益免费! 保姆级干货:在AI时代薅羊毛,如何获得大量免费的AI API?学完这个你的小龙虾就不缺粮食了! Deepseek-V4要来了的预兆?Deepseek专家模式低调上新!Deepseek首次引入模式分层! 游玩本站必读公告 Claude Code源代码惨遭泄露,几句话告诉你泄露的原因,附下载链接 Docker快速部署Astrbot,开源的一站式 Agentic 个人和群聊助手 今天是愚人节,请将这篇文章转发给你的亲朋好友 P1993 小 K 的农场 差分约束SPFA判断负环 详细题解 P6145 [USACO20FEB] Timeline G SPFA差分约束最长路题解 Luogu P2850 [USACO06DEC] Wormholes G SPFA算法思路与C++代码详解 Luogu P2136 拉近距离 SPFA判断负环题解 与 思路 开源 UI 元素社区库,让你的网站更加美观! 免费的AI和付费的API区别到底在哪里?付费的AI真的更聪明吗?
P4171 [JSOI2010] 满汉全席 2-SAT详细题解
PYM · 2026-03-28 · via PYM博客

题目传送门

前置知识:2-SAT

题目大意

n 种材料,每种可做满式(m)或汉式(h)m 位评审各有两个喜好(如 m1h2),只要选手做出其中一个喜好的菜,该评审就通过。

问:是否存在一种做菜方案,能让所有评审都通过

  • 存在输出 GOOD,否则输出 BAD

解题思路

显然这是一道2-SAT裸题。

分析题目

把每样材料拆成 ii 拆开,用 ii 表示满式做法,用 i+ni +n 表示汉式做法。

因为每个评委的要求只要满足一样的即可,所以可以看作是

uu 可以是满/汉式,点 vv 也可以是满/汉式,所以有4种情况

  1. 要求点 uu 是满式 或 点 vv 是满式,那么若 uu 为汉式,则 vv 必为满式;若 vv 为汉式,则 uu 必为满式。

  2. 要求点 uu 是满式 或 点 vv 是汉式,那么若 uu 为汉式,则 vv 必为汉式;若 vv 为汉式,则 uu 必为满式。

  3. 要求点 uu 是汉式 或 点 vv 是汉式,那么若 uu 为满式,则 vv 必为汉式;若 vv 为满式,则 uu 必为汉式。

  4. 要求点 uu 是汉式 或 点 vv 是满式,那么若 uu 为满式,则 vv 必为满式;若 vv 为汉式,则 uu 必为汉式。

建图

从上面的分析,我们可以得出通过特殊建图再跑一边板子2-SAT可以完成这道题。

for (int i = 1; i <= m; ++i) {
	string Su, Sv;
	cin >> Su >> Sv;
	char op1 = Su[0], op2 = Sv[0];
	int u = 0, v = 0;
	for (int j = 1; j < Su.size(); ++j) u = u * 10 + (Su[j] - '0' + 0);
	for (int j = 1; j < Sv.size(); ++j) v = v * 10 + (Sv[j] - '0' + 0);
	if (op1 == 'm') {
		if (op2 == 'h') add(v, u), add(u + n, v + n); // 第二种情况
		else add(u + n, v), add(v + n, u); // 第一种情况
	} else {
		if (op2 == 'h') add(u, v + n), add(v, u + n); // 第三种情况
		else add(u, v), add(v + n, u + n); // 第四种情况
	}
}

恭喜你这道题做完了。

判断GOOD还是BAD

因为 ii 为满式, i+ni + n 为汉式,所有只要判断 scc[i]==scc[i+n]scc[i] == scc[i+n]就可以了,如果相等就不成立,输出 BAD ,反之输出 GOOD

bool flag = true;
for (int i = 1; i <= n; ++i) {
	if (scc[i] == scc[i + n]) {
		flag = false;
		break;
	}
}
cout << (flag ? "GOOD" :  "BAD") << "\n";

AC代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1000 + 5;
int T;
int n, m;
vector<vector<int>> e;
void add(int u, int v) {
	e[u].emplace_back(v);
}
int tot, cnt;
int dfn[2 * N], low[2 * N], scc[2 * N];
stack<int> q;
bitset<2 * N> vis;
void tarjan(int u) {
	dfn[u] = low[u] = ++tot;
	q.emplace(u);
	vis[u] = true;
	for (auto v : e[u]) {
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
		} else if (vis[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		++cnt;
		int v;
		do {
			v = q.top(); q.pop();
			vis[v] = false;
			scc[v] = cnt;
		} while(v != u);
	}
}
void init() {
	cnt = tot = 0;
	e.clear();
	e.resize(2 * N);
	stack<int>().swap(q);
	vis.reset();
	for (int i = 1; i <= 2 * n; ++i) {
		dfn[i] = low[i] = scc[i] = 0;
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> T;
	while (T--) {
		init();
		cin >> n >> m;
		for (int i = 1; i <= m; ++i) {
			string Su, Sv;
			cin >> Su >> Sv;
			char op1 = Su[0], op2 = Sv[0];
			int u = 0, v = 0;
			for (int j = 1; j < Su.size(); ++j) u = u * 10 + (Su[j] - '0' + 0);
			for (int j = 1; j < Sv.size(); ++j) v = v * 10 + (Sv[j] - '0' + 0);
			if (op1 == 'm') {
				if (op2 == 'h') add(v, u), add(u + n, v + n);
				else add(u + n, v), add(v + n, u);
			} else {
				if (op2 == 'h') add(u, v + n), add(v, u + n);
				else add(u, v), add(v + n, u + n);
			}
		}
		for (int i = 1; i <= 2 * n; ++i) if (!dfn[i]) tarjan(i);
		bool flag = true;
		for (int i = 1; i <= n; ++i) {
			if (scc[i] == scc[i + n]) {
				flag = false;
				break;
			}
		}
		cout << (flag ? "GOOD" :  "BAD") << "\n";
	}
	return 0;
}