ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:
1. 选择一行, 该行每个格子的权值加1或减1。
2. 选择一列, 该列每个格子的权值加1或减1。
现在有K个限制,每个限制为一个三元组(x,y,c),代表格子(x,y)权值等于c。问是否存在一个操作序列,使得操作完后的矩阵满足所有的限制。如果存在输出”Yes”,否则输出”No”。

Input

先输入一个T(T <= 5)代表输入有T组数据,每组数据格式为:
第一行三个整数n, m, k (1 <= n, m,k <= 1000)。
接下来k行,每行三个整数x, y, c。

Output

对于每组数据,输出Yes或者No。
设x[i]=选择一行,该行每个格子的权值减1的次数-选择一行,该行每个格子的权值加1的次数
y[i]=选择一列, 该列每个格子的权值加1的次数-选择一列, 该列每个格子的权值减1的次数
每个约束条件即x[i]+c[i]=y[i]
建图,任意构造一个可行方案检查是否与条件矛盾
#include<cstdio>
int t,n,m,k;
int es[10000],enx[10000],e0[10000],ep=2;
int v[10000],ev[10000];
bool d[10000];
void addedge(int x,int y,int f){
    es[ep]=y;enx[ep]=e0[x];ev[ep]=f;e0[x]=ep++;
    es[ep]=x;enx[ep]=e0[y];ev[ep]=-f;e0[y]=ep++;
}
bool flag;
void dfs(int w){
    d[w]=1;
    for(int i=e0[w];i&&flag;i=enx[i]){
        int u=es[i];
        if(d[u]){
            if(v[u]!=v[w]+ev[i])flag=0;
        }else{
            v[u]=v[w]+ev[i];
            dfs(u);
        }
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&k);
        ep=2;
        for(int i=1;i<=n+m;i++)d[i]=e0[i]=v[i]=0;
        for(int i=0,x,y,c;i<k;i++){
            scanf("%d%d%d",&x,&y,&c);
            addedge(x+n,y,c);
        }
        flag=1;
        for(int i=1;flag&&i<=n+m;i++){
            if(!d[i])dfs(i);
        }
        puts(flag?"Yes":"No");
    }
    return 0;
}

 

posted on 2016-04-07 21:29  nul  阅读(659)  评论(0编辑  收藏  举报