hdu 4665 (dfs / 2-SAT)

来源:互联网 发布:js弹出框 编辑:程序博客网 时间:2024/06/05 07:33

题目链接


多校第六场的题目, 比赛时没什么想法, 后来看GYZ神犇的解题报告里用的是O(n ^ 2)的2 - SAT解法, 但本弱菜还是没想到如何构图, 后来看别人都是用dfs过的, 自己写了一版觉得还是挺好写的, 而且速度也很快, 但复杂度不知如何分析, 一开始觉得dfs应该会T的, 毕竟需要递归2000层, 后来想了想觉得这题有一定的特殊性, 因为题目只要求输出一组解, 而且如果相同同种颜色很多的话解的个数也会多, 所以dfs速度会比较快, 但准确的理论复杂度还是不知如何分析, 有时间再研究2-SAT解法吧。。。。。


#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <vector>#include <queue>#include <string>#include <cctype>#include <set>#include <deque>#include <map>using namespace std;inline int readint() {char c = getchar();while (!isdigit(c)) c = getchar();int x = 0;while (isdigit(c)) {x = x * 10 + c - '0';c = getchar();}return x;}int buf[10];inline void writeint(int x) {int p = 0;if (x == 0) p++;else while (x) {buf[p++] = x % 10;x /= 10;}for (int j = p - 1; j >= 0; j--)putchar('0' + buf[j]);}const int N = 2005;int cnt0[N], cnt1[N], sum[N];int res[N], s0[N], s1[N], str[N];int n;bool ok = 0;void dfs(int id, int sz0, int sz1) {if (id == n + 1) {for (int i = 1; i <= n; i++) printf("%d", res[i]);puts("");ok = 1;return;}if (cnt0[str[id]] < sum[str[id]] / 2 && (sz0 >= sz1 || str[id] == s1[sz0])) {res[id] = 0;cnt0[str[id]]++;s0[sz0] = str[id];dfs(id + 1, sz0 + 1, sz1);if (ok) return;cnt0[str[id]]--;}if (cnt1[str[id]] < sum[str[id]] / 2 && (sz1 >= sz0 || str[id] == s0[sz1])) {res[id] = 1;cnt1[str[id]]++;s1[sz1] = str[id];dfs(id + 1, sz0, sz1 + 1);if (ok) return;cnt1[str[id]]--;}}int main() {int test;test = readint();while (test--) {n = readint();for (int i = 1; i <= n; i++)cnt0[i] = 0, cnt1[i] = 0, sum[i] = 0;for (int i = 1; i <= n; i++)str[i] = readint(), sum[str[i]]++;ok = 0;s0[1] = str[1];cnt0[str[1]]++;dfs(2, 2, 1);}return 0;}

原创粉丝点击