BZOJ4500: 矩阵
【传送门:BZOJ4500】
简要题意:
有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:
1.选择一行,该行每个格子的权值加1或减1
2.选择一列,该列每个格子的权值加1或减1
有k个约束条件,x,y,c表示第x行第y列的格子为c
如果有满足情况的矩阵就输出Yes,否则输出No
题解:
设初始权值为1
对于约束条件的处理,则将x连向y,权值为c
然后DFS,如果有不满足的就退出,一个一个点地遍历判断
参考代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; struct node { int x,y,d,next; }a[2100];int len,last[2100]; void ins(int x,int y,int d) { len++; a[len].x=x;a[len].y=y;a[len].d=d; a[len].next=last[x];last[x]=len; } bool v[2100]; int d[2100]; bool bk; void dfs(int x) { if(bk==false) return ; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(v[y]==false) { v[y]=true; d[y]=a[k].d-d[x]; dfs(y); } else if(d[y]!=a[k].d-d[x]){bk=false;return ;} } } int main() { int T; scanf("%d",&T); while(T--) { int n,m,k; scanf("%d%d%d",&n,&m,&k); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=k;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); ins(x,y+n,c);ins(y+n,x,c); } bk=true; memset(v,false,sizeof(v)); for(int i=1;i<=n+m;i++) { if(v[i]==false) { d[i]=1;v[i]=true; dfs(i); if(bk==false) break; } } if(bk==false) printf("No\n"); else printf("Yes\n"); } return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚