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