请不要随便指点别人该怎么做、每个人的人生都应该自己掌握、你给不了别人一切、你也不懂别人的忧伤、
微笑不代表快乐、哭泣不一定悲伤
不努力怎么让关心你的人幸福、不努力怎么让看不起你的人绝望、
我用生命在奋斗——lx_Zz
—————————————————————————————————————————————————————————————
————————————————————————— 华丽的分割线 ————————————————————————————
—————————————————————————————————————————————————————————————
唉、弱的一B、什么都不想说了、继续切题。。。
/* 题目: Interesting matrix */ /* 作者: lx_Zz */ /* 时间: 2014.5.19 */ #include<cstdio> #include<queue> #include<vector> #include<map> #include<string> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=105*105;//点数的最大值 const int MAXM=105*105*10;//边数的最大值 int num[105][105]; struct Node { int from,to,next; int cap; }edge[MAXM]; int tol; int dep[MAXN];//dep为点的层次 int head[MAXN]; int n; void init() { tol=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w)//第一条变下标必须为偶数 { edge[tol].from=u; edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u]; head[u]=tol++; edge[tol].from=v; edge[tol].to=u; edge[tol].cap=0; edge[tol].next=head[v]; head[v]=tol++; } int BFS(int start,int end) { int que[MAXN]; int front,rear; front=rear=0; memset(dep,-1,sizeof(dep)); que[rear++]=start; dep[start]=0; while(front!=rear) { int u=que[front++]; if(front==MAXN)front=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(edge[i].cap>0&&dep[v]==-1) { dep[v]=dep[u]+1; que[rear++]=v; if(rear>=MAXN)rear=0; if(v==end)return 1; } } } return 0; } int dinic(int start,int end) { int res=0; int top; int stack[MAXN];//stack为栈,存储当前增广路 int cur[MAXN];//存储当前点的后继 while(BFS(start,end)) { memcpy(cur,head,sizeof(head)); int u=start; top=0; while(1) { if(u==end) { int min=INF; int loc; for(int i=0;i<top;i++) if(min>edge[stack[i]].cap) { min=edge[stack[i]].cap; loc=i; } for(int i=0;i<top;i++) { edge[stack[i]].cap-=min; edge[stack[i]^1].cap+=min; } res+=min; top=loc; u=edge[stack[top]].from; } for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) break; if(cur[u]!=-1) { stack[top++]=cur[u]; u=edge[cur[u]].to; } else { if(top==0)break; dep[u]=-1; u=edge[stack[--top]].from; } } } return res; } int main() { //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_in.txt","r",stdin); //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_out.txt","w",stdout); int T; int start,end; scanf("%d",&T); while(T--) { scanf("%d",&n); int tt=0; int maxx=0; int count=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&num[i][j]); if(num[i][j]==-1)count++; tt=max(tt,num[i][j]); } } while(tt) { tt=tt/2; maxx++; } int t=0; int ans=0; int tmp=1; start=0,end=n*n+1; while(t<maxx) { init(); for(int j=1;j<n;j++) { add(j,j+1,1); add(j+1,j,1); } for(int i=2;i<=n;i++) { int x=(i-1)*n; for(int j=1;j<n;j++) { add(x+j,x+j+1,1); add(x+j+1,x+j,1); add(x+j,x-n+j,1); add(x-n+j,x+j,1); } add(x+n,x,1); add(x,x+n,1); } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(num[i][j]==-1)continue; int x=(i-1)*n+j; int temp=(num[i][j]>>t)&1; if(temp==1) { add(start,x,INF); } else { add(x,end,INF); } } } int w=dinic(start,end); if(w>0) ans=(ans+w*tmp); tmp*=2; t++; } printf("%d\n",ans); } return 0; }