SPOJ SOPARADE(JZOJ 4696 第四次忍者大战) 根据条件构图跑2-SAT
来源:互联网 发布:用php写一个 编辑:程序博客网 时间:2024/06/06 07:46
题目大意
现在有
解题思路
我们一步步从题目的约束中挖掘性质。
首先,相邻的两个数的差的大于等于2,那么1的傍边只能是3,4。2的旁边只能是4。3的旁边只能是1。4的旁边只能是1,2。我们发现1,2和3,4的填入肯定是交错的,就是说奇数位一定是1,2,偶数位一定是3,4(反过来也行,没什么区别)。那么对于一个点就只有两个选择,那么这就非常像2-SAT了。
那么我们就按2-SAT的方式连边,比如奇数位的2就一定要像右边的偶数位的4连一条边,因为选了2就只能在旁边选4。类似的我们就解决了相邻的性质。对于
提示:解决相邻的约束时,只用从前面往后面连边。因为我们做2-SAT时是默认了做完了前
程序
十分丑的代码。。。
//YxuanwKeith#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 2e5 + 5;int N, M, c, Test, S[MAXN];int tot, Last[MAXN], Next[MAXN * 40], Go[MAXN * 40];bool mark[MAXN];void Link(int a, int b) { Next[++ tot] = Last[a], Last[a] = tot, Go[tot] = b;}void Read(int &Now) { char ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); Now = 0; while (ch >= '0' && ch <= '9') Now = Now * 10 + ch - '0', ch = getchar();}bool Dfs(int x) { int y = (x & 1) ? (x + 1) : (x - 1); if (mark[y]) return 0; if (mark[x]) return 1; mark[x] = 1; S[c ++] = x; for (int p = Last[x]; p; p = Next[p]) if (!Dfs(Go[p])) return 0; return 1;}bool Solve() { memset(mark, 0, sizeof mark); memset(Last, 0, sizeof Last); tot = 0; Read(N), Read(M); for (int i = 1; i < N; i ++) { int a = i, b = i + 1; Link(a * 2, b * 2 - 1); } for (int i = 1; i <= M; i ++) { int Num; Read(Num); if (Num > 4) return 0; static int _0[3], _1[3]; _0[0] = _1[0] = 0; for (int j = 0; j < Num; j ++) { int Now; Read(Now); if (Now & 1) _0[++ _0[0]] = Now; else _1[++ _1[0]] = Now; } if (_0[0] > 2 || _1[0] > 2) return 0; if (_0[0] > 1) { Link(_0[1] * 2, _0[2] * 2 - 1); Link(_0[1] * 2 - 1, _0[2] * 2); Link(_0[2] * 2, _0[1] * 2 - 1); Link(_0[2] * 2 - 1, _0[1] * 2); }; if (_1[0] > 1) { Link(_1[1] * 2, _1[2] * 2 - 1); Link(_1[1] * 2 - 1, _1[2] * 2); Link(_1[2] * 2, _1[1] * 2 - 1); Link(_1[2] * 2 - 1, _1[1] * 2); } } for (int i = 1; i <= N * 2; i += 2) { if (!mark[i] && !mark[i + 1]) { c = 0; if (!Dfs(i)) { while (c > 0) mark[S[-- c]] = 0; if (!Dfs(i + 1)) return 0; } } } return 1;}int main() { int Test; scanf("%d", &Test); for (int i = 1; i <= Test; i ++) { if (Solve()) printf("approved\n"); else printf("rejected\n"); }}
2 0
- SPOJ SOPARADE(JZOJ 4696 第四次忍者大战) 根据条件构图跑2-SAT
- 【搬自Spoj-SOPARADE】第四次忍者大战 题解
- SPOJ SOPARADE
- ninja (Spoj-SOPARADE)
- 【SPOJ-KING】King【2-SAT】
- JZOJ4696.第四次忍者大战
- SPOJ 962 - Intergalactic Map 1<-2->3 构图最大流
- poj 2723 Get Luffy Out(2-sat构图题)
- Uva 1146 - Now or later 二分+构图2-sat判断
- HDOJ 1816 - Get Luffy Out * 构图2-sat...
- POJ 2296 - Map Labeler 构图2-sat..注意细节...
- poj 2296 Map Labeler(2-SAT+二分,构图)
- 【GDOI2017模拟8.14】第四次忍者大战
- CodeForces 27D - Ring Road 2 构图2-sat..并输出选择方案
- POJ 3207 - Ikki's Story IV - Panda's Trick 构图2-sat
- POJ 3678 - Katu Puzzle 比较典型的构图2-sat...求是否有可行解
- POJ 2749 - Building roads 构图2-sat..注意!POJ爆WA也有可能是数组越界!
- Uva1 1391/LA 3713 - Astronauts 构图2-sat...更正了toposort过程...
- spring声明式事物管理配置和对c3p0连接池的详细配置
- strstr函数的精彩之处
- mongodb 计算坐标距离
- Android工具类---格式化文件
- [BZOJ3895]取石子(博弈+记搜)
- SPOJ SOPARADE(JZOJ 4696 第四次忍者大战) 根据条件构图跑2-SAT
- HDU 1556 Color the ball
- JZOJ4703 Buy
- 指数级增长背后,滴滴出行业务系统的架构升级
- Java反射与泛型的本质
- linux crontab
- hdoj 5839 Special Tetrahedron 叉积点积判断四点共面模板
- 多个线程之间如何进行通信
- SecureCRT校准四轴电调