m 个约束条件,第 j 个约束条件有四个整数 u,x,v,y,表示 au=x与 av=y两者至少有一个成立。请判断是否至少存在一组 a 的值满足上述条件。
这里的边(箭头)表示逻辑蕴含关系,因此同一个强连同分量内的变量值一定是同时成立的。也就是说,如果出现了如非a和a在同一个强连通分量里,那么就出现了矛盾,这个方程组是无解的。
#include<cstdio>
#include<vector>
#include<stack>
using namespace std;
int n, m;
#define maxn 2000005
vector<int> vec[maxn];
int low[maxn], dfn[maxn],color[maxn], cnt = 0,cnt2 = 0;
bool vis[maxn];
stack<int> sta;
void tarjan(int u) {
low[u] = dfn[u] = ++cnt;
sta.push(u);
vis[u] = true;
for (int v : vec[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]) {
cnt2++;
while (sta.top() != u) {
color[sta.top()] = cnt2;
vis[sta.top()] = 0;
sta.pop();
}
color[sta.top()] = cnt2;
vis[sta.top()] = 0;
sta.pop();
}
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, x, v, y;
scanf("%d %d %d %d", &u, &x, &v, &y);
//建图
if (!x && !y) {
vec[u + n].push_back(v);
vec[v + n].push_back(u);
} else
if (!x && y) {
vec[v].push_back(u);
vec[u + n].push_back(v+n);
} else
if (x && !y) {
vec[v + n].push_back(u+n);
vec[u].push_back(v);
} else
if (x && y) {
vec[u].push_back(v + n);
vec[v].push_back(u + n);
}
}
for (int i = 1; i <= n * 2; i++) {
if (!dfn[i]) tarjan(i);
}
for (int i = 1; i <= n; i++) {
if (color[i] == color[i + n]) {
printf("NO");
return 0;
}
}
printf("YES");
}