P4171 满汉全席
题意简述
m
时是满式,为h
时是汉式。问是否有一种方案,使得每组要求至少可以满足其中一个要求。
解题思路
因为不做满式就只能做汉式,所以整理得到:
容易发现上述条件关系有一定的奇偶关系,所以可以用
u = u * 2 + (t1 == 'h');
v = v * 2 + (t2 == 'h');
add(u ^ 1, v), add(v ^ 1, u);
然后跑 Tarjan
, 如果一个菜满式和汉式在同一个分量里,就无解
代码
#include <iostream>
#include <cstring>
#include <vector>
#define init(x, y) memset(x, y, sizeof x)
using namespace std;
const int N = 2010;
int e[N], ne[N], h[N], idx;
int stmp, dfn[N], low[N];
int ins[N], stk[N], tt;
int n, m, scc_cnt, id[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u)
{
dfn[u] = low[u] = ++ stmp;
stk[ ++ tt] = u, ins[u] = 1;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (!dfn[j]) dfs(j);
if (ins[j]) low[u] = min(low[u], low[j]);
}
if (low[u] == dfn[u])
{
int y; ++ scc_cnt;
do {
y = stk[tt -- ], ins[y] = 0;
id[y] = scc_cnt;
} while (y != u);
}
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
init(h, -1), init(dfn, 0);
tt = scc_cnt = idx = 0;
scanf("%d%d", &n, &m);
while (m -- )
{
char t1, t2;
int u, v;
scanf(" %c%d %c%d", &t1, &u, &t2, &v);
u --, v --;
u = u * 2 + (t1 == 'h');
v = v * 2 + (t2 == 'h');
add(u ^ 1, v), add(v ^ 1, u);
}
for (int i = 0; i < 2 * n; i ++ )
if (!dfn[i]) dfs(i);
int flag = 1;
for (int i = 0; i < n && flag; i ++ )
if (id[i * 2] == id[i * 2 + 1]) flag = 0;
puts(flag ? "GOOD" : "BAD");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)