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;
}

 

posted @ 2018-03-22 16:52  Star_Feel  阅读(323)  评论(0编辑  收藏  举报