#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 510; struct Edge { int to,next; Edge(){} Edge(int _to,int _next):to(_to),next(_next){} }e[MAXN*MAXN*4+1100]; int head[MAXN*3],tot; void init(){ memset(head,-1,sizeof(head)); tot=0; } void AddEdge(int u,int v){ e[tot]=Edge(v,head[u]); head[u]=tot++; } int dfn[MAXN*3],low[MAXN*3],sta[MAXN*3],bleg[MAXN*3]; int times,top; void tarjan(int u){ dfn[u]=low[u]=++times; sta[++top]=u; for(int i=head[u];~i;i=e[i].next){ int v=e[i].to; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(!bleg[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ ++bleg[0]; do { bleg[sta[top]]=bleg[0]; }while(sta[top--]!=u); } } void print(int u,int v){ printf("%d%c-->%d%c\n",u>>1,(u&1)?'\'':' ',v>>1,(v&1)?'\'':' '); } int b[MAXN][MAXN],n; int main() { 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]!=0)flag=1; for(int j=i+1;j<n;j++){ if(b[i][j]!=b[j][i])flag=1; } } for(int k=0;k<32&&!flag;k++){ init(); for(int i=0;i<n&&!flag;i++) for(int j=0;j<n&&!flag;j++){ if(i==j)continue; int t=(b[i][j]>>k)&1; int aa=i+1,bb=j+1; if(i%2==1&&j%2==1){ if(t){ AddEdge(aa<<1|1,bb<<1); AddEdge(bb<<1|1,aa<<1); } else { AddEdge(aa<<1,aa<<1|1); AddEdge(bb<<1,bb<<1|1); } } else if(i%2==0&&j%2==0){ if(t){ AddEdge(aa<<1|1,aa<<1); AddEdge(bb<<1|1,bb<<1); } else { AddEdge(aa<<1,bb<<1|1); AddEdge(bb<<1,aa<<1|1); } } else { if(t){ AddEdge(aa<<1,bb<<1|1);AddEdge(bb<<1|1,aa<<1); AddEdge(bb<<1,aa<<1|1);AddEdge(aa<<1|1,bb<<1); } else { AddEdge(aa<<1,bb<<1);AddEdge(bb<<1,aa<<1); AddEdge(aa<<1|1,bb<<1|1);AddEdge(bb<<1|1,aa<<1|1); } } } memset(dfn,0,sizeof(dfn)); memset(bleg,0,sizeof(bleg)); times=top=0; for(int i=1;i<=n;i++){ if(!dfn[i<<1])tarjan(i<<1); if(!dfn[i<<1|1])tarjan(i<<1|1); } for(int i=1;i<=n;i++) if(bleg[i<<1]==bleg[i<<1|1])flag=1; if(flag)break; } if(flag)puts("NO"); else puts("YES"); } return 0; }
|