标签:
题目大意:小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
―― 余光中
集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。
解题思路:首先,为队长和每个队员建立限制条件
假设队长是a,另外两个队员是b和c,
队长回去的时候,两个队员都要在,也就是不能回去,那么就要满足 (a V !b) &&(a V !c)
队员回去时,队长不可以回去,那么就要满足(c V b) && !a,转换一下就变成了(c V !a)&& (b V !a)
然后又给出了如果一个队员要留着,另外一个队员必须要回去的条件,假设队员为a和b,那么就要满足
(a V !b) && (b V !a)
这样就建图完成了
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define N 6010
vector<int> G[N];
int n, m, top;
bool mark[N];
int S[N];
void init() {
for (int i = 0; i < 6 * n; i++)
G[i].clear();
int x, y, z;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &x, &y, &z);
G[2 * x].push_back(2 * y + 1);
G[2 * x].push_back(2 * z + 1);
G[2 * y].push_back(2 * x + 1);
G[2 * z].push_back(2 * x + 1);
}
for (int i = 0; i < m; i++) {
scanf("%d%d", &x, &y);
G[2 * y + 1].push_back(2 * x);
G[2 * x + 1].push_back(2 * y);
}
}
bool dfs(int u) {
if (mark[u ^ 1])
return false;
if (mark[u])
return true;
mark[u] = true;
S[++top] = u;
for (int i = 0; i < G[u].size(); i++)
if (!dfs(G[u][i]))
return false;
return true;
}
void solve() {
memset(mark, 0, sizeof(mark));
for (int i = 0; i < 6 * n; i += 2) {
top = 0;
if (!dfs(i)) {
while (top)
mark[S[top--]] = false;
if (!dfs(i ^ 1)) {
printf("no\n");
return ;
}
}
}
printf("yes\n");
}
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU - 1824 Let's go home(2-SAT)
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/47385911