Http://acm.zju.edu.cn/onlinejudge/showProblem.do?
problemid=4879
Tle for an afternoon. And then there's no way to find out. The idea was almost the same as mine, but it was my T. Then the array was enlarged and then AC, without words.
According to my estimate 500 points open to 1000+ is enough, but not strange not understand ...
YES or no question, generally is and check set with 2-sat the problem and check the set to write more easy
http://blog.csdn.net/u011026968/article/details/10823853
Look at the question Poj 3678 can be found after reading, just to each one as poj3678 executed 32 times then OK
The method of building the map is the same as poj3678
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < Stack> #include <iostream>using namespace std; #define CL (A, B) memset (A,b,sizeof (a)) #define in (s) freopen (s, "R ", stdin) const int MAXN = 6000;int n,b[505][505];int head[maxn],dfn[maxn],low[maxn],id[maxn];int cnt,scnt;stack<int >st;struct node{int to,nxt;} edge[1000010];///inline void Addedge (int u,int v,int k) {edge[k].to=v; Edge[k].nxt=head[u]; Head[u]=k; printf ("u=%d v=%d k=%d\n", u,v,k);} void Tarjan (int u) {int v,i,min1=dfn[u]=low[u]=cnt++; St.push (U); for (I=HEAD[U];I!=-1;I=EDGE[I].NXT) {v=edge[i].to; if (dfn[v]==-1) Tarjan (v); Min1=min (Min1,low[v]); } if (Min1<low[u]) {Low[u]=min1;return;} do {v=st.top (); id[v]=scnt; St.pop (); low[v]=n*2; }while (V!=u); scnt++;} int solve (int pos) {CL (DFN,0XFF); CL (ID,0XFF); CL (HEAD,0XFF); CL (LOW,0XFF); scnt=cnt=0; WhilE (!st.empty ()) St.pop (); int num=0; for (int i=0;i<n;i++) for (int j=0;j<n;j++) {if (i==j) continue;///int f= (B[I][J] >>pos) &1; printf ("pos=%d bij=%d f=%d\n", pos,b[i][j],f); if (i%2 && j%2) {if (f) {Addedge (i,j+n,num++); Addedge (j,i+n,num++); } else {Addedge (i+n,i,num++); Addedge (j+n,j,num++); Addedge (i,j,num++); Addedge (j,i,num++); } continue; } if (i%2==0 && j%2==0) {if (f) {Addedge (I, i+n,num++); Addedge (j,j+n,num++); Addedge (i+n,j+n,num++); Addedge (j+n,i+n,num++); } else {Addedge (j+n,i,num++); Addedge (i+n,j,num++); } continue; } if (f) {Addedge (i,j+n,num++); Addedge (j+n,i,num++); Addedge (j,i+n,num++); Addedge (i+n,j,num++); } else {Addedge (i,j,num++); Addedge (j,i,num++); Addedge (i+n,j+n,num++); Addedge (j+n,i+n,num++); }} int flag=1; for (int i=0;i<n*2;i++) if (dfn[i] = =-1) {//////////printf ("tari=%d\n", I); Tarjan (i); } for (int i=0;i<n;i++) if (id[i] = = Id[i+n])//In the same connected component {flag=0; Break } if (flag) return 1; else return 0;} int main () {//in ("zoj3656.txt"); while (~SCANF ("%d", &n)) {for (Int. i=0;i<n;i++) for (int j=0;j<n;j++) scanf ("%d", &b[i][j]); int flag=0; for (int i=0;i<n;i++) {if (B[i][i]) {flag=2; Puts ("NO"); Break }} if (flag==2) continue; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) {if (B[i][j]!=b[j][i]) {flag=2; Puts ("NO"); Break }} if (flag==2) continue; for (int i=0;i<32;i++) {flag=solve (i); if (flag==0) break; } if (!flag) puts ("NO"); Else puts ("YES"); } return 0;}
and the practice code of the check set is short a lot of good bad looks http://blog.csdn.net/lasolmi/article/details/38979207
Another method of building a map, the internet to find faster 20ms is not very understanding of the said
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < Stack> #include <iostream>using namespace std; #define CL (A, B) memset (A,b,sizeof (a)) #define in (s) freopen (s, "R ", stdin) const int MAXN = 6000;int n,b[505][505];int head[maxn],dfn[maxn],low[maxn],id[maxn];int cnt,scnt;stack<int >st;struct node{int to,nxt;} edge[1000010];///inline void Addedge (int u,int v,int k) {edge[k].to=v; Edge[k].nxt=head[u]; Head[u]=k; printf ("u=%d v=%d k=%d\n", u,v,k);} void Tarjan (int u) {int v,i,min1=dfn[u]=low[u]=cnt++; St.push (U); for (I=HEAD[U];I!=-1;I=EDGE[I].NXT) {v=edge[i].to; if (dfn[v]==-1) Tarjan (v); Min1=min (Min1,low[v]); } if (Min1<low[u]) {Low[u]=min1;return;} do {v=st.top (); id[v]=scnt; St.pop (); low[v]=n*2; }while (V!=u); scnt++;} int solve (int pos) {CL (DFN,0XFF); CL (ID,0XFF); CL (HEAD,0XFF); CL (LOW,0XFF); scnt=cnt=0; WhilE (!st.empty ()) St.pop (); int num=0; for (int i=0;i<n;i++) for (int j=0;j<n;j++) {if (i==j) continue;///int f= (B[I][J] >>pos) &1; printf ("pos=%d bij=%d f=%d\n", pos,b[i][j],f); if (i%2 && j%2) {if (f) {//addedge (i,j+n,num++); Addedge (j,i+n,num++); Addedge (i+n,j,num++); Addedge (j+n,i,num++); } else {Addedge (i,i+n,num++); Addedge (j,j+n,num++); Addedge (i+n,i,num++); Addedge (j+n,j,num++); Addedge (i,j,num++); Addedge (j,i,num++); } continue; } if (i%2==0 && j%2==0) {if (f) {Addedge (i+ N,i,num++); Addedge (j+n,j,num++); Addedge (i,i+n,num++); Addedge (j,j+n,num++); Addedge (i+n,j+n,num++); Addedge (j+n,i+n,num++); } else {Addedge (i,j+n,num++); Addedge (j,i+n,num++); Addedge (j+n,i,num++); Addedge (i+n,j,num++); } continue; } if (f) {Addedge (i,j+n,num++); Addedge (j+n,i,num++); Addedge (j,i+n,num++); Addedge (i+n,j,num++); } else {Addedge (i,j,num++); Addedge (j,i,num++); Addedge (i+n,j+n,num++); Addedge (j+n,i+n,num++); }} int flag=1; for (int i=0;i<n*2;i++) if (dfn[i] = =-1) {////////printf ("tari=%d\n", I); Tarjan (i); } for (int i=0;i<n;i++) if (id[i] = = Id[i+n])//In the same connected component {flag=0; Break } if (flag) return 1; else return 0;} int main () {//in ("zoj3656.txt"); while (~SCANF ("%d", &n)) {for (Int. i=0;i<n;i++) for (int j=0;j<n;j++) scanf ("%d ", &b[i][j]); int flag=0; for (int i=0;i<n;i++) {if (B[i][i]) {flag=2; Puts ("NO"); Break }} if (flag==2) continue; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) {if (B[i][j]!=b[j][i]) {flag=2; Puts ("NO"); Break }} if (flag==2) continue; for (int i=0;i<32;i++) {flag=solve (i); if (flag==0) BreAk } if (!flag) puts ("NO"); Else puts ("YES"); } return 0;}
Zoj 3656 2-sat a good question