传送门:点击打开链接
题意:n对夫妻,一对夫妻必须去1人,有m对人互相讨厌,不能同时去,问是否有这样的情况。
思路:2SAT...
#include <map> #include <set> #include <cmath> #include <ctime> #include <stack> #include <queue> #include <cstdio> #include <cctype> #include <bitset> #include <string> #include <vector> #include <cstring> #include <iostream> #include <algorithm> #include <functional> #define fuck(x) cout<<"["<<x<<"]"; #define FIN freopen("input.txt","r",stdin); #define FOUT freopen("output.txt","w+",stdout); //#pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef long long LL; typedef pair<int, int> PII; const int MX = 2e3 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; struct Edge { int v, nxt; } E[MX * MX * 2]; int Head[MX][2], erear; void edge_init() { erear = 0; memset(Head, -1, sizeof(Head)); } void edge_add(int z, int u, int v) { E[erear].v = v; E[erear].nxt = Head[u][z]; Head[u][z] = erear++; } void edge_add(int u, int v) { edge_add(0, u, v); edge_add(1, v, u); } int Stack[MX], Belong[MX], vis[MX], ssz, bsz; void DFS(int u, int s) { vis[u] = 1; if(s) Belong[u] = s; for(int i = Head[u][s > 0]; ~i; i = E[i].nxt) { int v = E[i].v; if(!vis[v]) DFS(v, s); } if(!s) Stack[++ssz] = u; } void tarjan(int n) { ssz = bsz = 0; for(int i = 1; i <= n; i++) vis[i] = 0; for(int i = 1; i <= n; i++) { if(!vis[i]) DFS(i, 0); } for(int i = 1; i <= n; i++) vis[i] = 0; for(int i = ssz; i >= 1; i--) { if(!vis[Stack[i]]) DFS(Stack[i], ++bsz); } } int main() { int n, m; //FIN; while(~scanf("%d%d", &n, &m)) { edge_init(); for(int i = 1; i <= m; i++) { int u, v, c1, c2; scanf("%d%d%d%d", &u, &v, &c1, &c2); u++; v++; edge_add(u + (c1 ? n : 0), v + (c2 ? 0 : n)); edge_add(v + (c2 ? n : 0), u + (c1 ? 0 : n)); } tarjan(2 * n); bool ans = true; for(int i = 1; i <= n; i++) { if(Belong[i] == Belong[i + n]) { ans = false; break; } } printf("%s\n", ans ? "YES" : "NO"); } return 0; }