Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=3062
Problem description There are N couples invited to a party, because of the problem of the site, only 1 people per couple can attend. In 2n individuals, some people have a great contradiction (of course, there is no contradiction between the couple), there are contradictions between the 2 people will not appear at the party at the same time. Is there any possibility that there will be n individuals attending at the same time? INPUTN: Indicates that there are N couples invited (n<= 1000)
M: Indicates having M-to-contradict relationship (M < (n-1) * (n-1))
In the next M-line, there are 4 numbers per row, respectively, A1,A2,C1,C2
A1,A2 is the couple's number, respectively.
C1,c2 says wife or husband, 0 means wife, 1 is husband.
Couple numbers from 0 to n-1
Output Yes if there is a situation
Otherwise output NO
Sample Input
Sample Output
YES
Source2009 multi-university Training Contest 16-host by NIT
The code is as follows:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace STD; #define M 4000017#define N 100017//a<<1 and (a<<1) + 1. A<<1 means that the wife, (a<<1) + 1 means that the husband//connection to a certain side is to introduce contradictions. X->y that the selected x must be selected y//note the direction of the struct node{int s, t; int NXT;} E[m];int N, M;int idx, ans, TP, cont;int dfn[n],vis[n],low[n],head[n],st[n],belong[n];void Add (int s,int t) {E[CONT].S = S; e[cont].t = t; E[CONT].NXT = Head[s]; Head[s] = cont++;} void Build_grap (int a, int b, int c, int d)//map {if (c==0 && d==0)//Two wives {Add (a<<1, b<<1 ) +1); Add (b<<1, (a<<1) + 1); } else if (c==0 && d==1)//wife and husband {Add ((a<<1), (b<<1)); Add ((b<<1) +1, (a<<1) +1); } else if (c==1 && d==0)//husband and wife {Add ((a<<1) + 1, (b<<1) + 1); Add (b<<1, a<<1); } else if (c==1 && d==1)//Two husbands have a contradiction {add ((a<<1) +1, b<<1); Add ((b<<1) +1, a<<1); }}void Tarjan (int u) {dfn[u] = low[u] = ++idx; Vis[u] = 1; ST[++TP] = u; int V; for (int i = head[u]; I! =-1; i = e[i].nxt) {v = e[i].t; if (!dfn[v]) {Tarjan (v); Low[u] = min (low[u],low[v]); } else if (Vis[v]) low[u] = min (low[u],dfn[v]); } if (dfn[u] = = Low[u]) {ans++; while (1) {v = st[tp--]; VIS[V] = 0; Belong[v] = ans; if (v = = u) break; }}}bool _2sat () {memset (vis,0,sizeof (VIS)); memset (dfn,0,sizeof (DFN)); IDX = TP = ans = 0; for (int i = 0; i < 2*n; i++) if (!dfn[i]) Tarjan (i); for (int i = 0; i < n; i++) if (belong[2*i]==belong[(2*i) ^1])//contradiction return false; return true;} int main () {int A, B, C, D; while (~SCANF ("%d%d", &n,&m)) {cont = 0; memset (head,-1, sizeof (head)); for (int i = 0; i < m; i++) {scanf ("%d%d%d%d", &a,&b,&c,&d); int u, v; u = a*2+c; v = b*2+d; Add (U, v^1); Add (V, u^1); Build_grap (A, B, C, D); } if (_2sat ()) printf ("yes\n"); else printf ("no\n"); } return 0;}
HDU 3062 Party (2-sat template title Tarjan)