题目:

Description

有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:

  1. 选择一行, 该行每个格子的权值加1或减1。
  2. 选择一列, 该列每个格子的权值加1或减1。

    现在有K个限制,每个限制为一个三元组(x,y,c),代表格子(x,y)权值等于c。

    问是否存在一个操作序列,使得操作完后的矩阵满足所有的限制。如果存在输出”Yes”,否则输出”No”。

题解:

如果我们将所有的行作为变量\(x\),所有的列作为变量\(y\).

变量本身代表对这行(列)进行的操作数(x,y可以为负)

所以对于每一个三元限制我们可以列出方程\(x_i + y_i = c_i\)

然后我们移项得到\(x_i - c_i = y_i\)

这样我们可以依据这个等式列出两个不等式:

  • $ x_i - c_i \leq y_i $
  • $ y_i - (-c_i) \leq x_i $

然后我们建立差分约束系统,dfs判正环即可.

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 2048;
const int maxm = 1024*1024;
struct Edge{
int to,next,dis;
}G[maxm];
int head[maxn],cnt;
void add(int u,int v,int d){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
G[cnt].dis = d;
}
int dis[maxn];bool inq[maxn];
inline void init(){
memset(head,0,sizeof head);
memset(dis,-0x3f,sizeof dis);
memset(inq,false,sizeof inq);
cnt = 0;
}
#define v G[i].to
bool dfs(int u){
inq[u] = true;
for(int i = head[u];i;i=G[i].next){
if(dis[v] < dis[u] + G[i].dis){
dis[v] = dis[u] + G[i].dis;
if(inq[v]) return false;
if(!dfs(v)) return false;
}
}
inq[u] = false;
return true;
}
#undef v
int x[maxn],y[maxn],c[maxn];
int work(){
init();
int n,m,k;read(n);read(m);read(k);
for(int i=1;i<=k;++i) read(x[i]),read(y[i]),read(c[i]);
for(int i=1;i<=k;++i){
for(int j=1;j<=k;++j){
if(x[i] == x[j] && y[i] == y[j] && c[i] != c[j]) return puts("No");
if(x[i] == x[j] && y[i] == y[j]) continue;
if(x[i] == x[j] && c[i] - c[j] >= 0){
add(y[j]+n,y[i]+n,c[i]-c[j]);
add(y[i]+n,y[j]+n,c[j]-c[i]);
}
if(y[i] == y[j] && c[i] - c[j] >= 0){
add(x[j],x[i],c[i]-c[j]);
add(x[i],x[j],c[j]-c[i]);
}
}
}
for(int i=1;i<=n+m;++i) if(!dfs(i)) return puts("No");
return puts("Yes");
}
int main(){
int T;read(T);
while(T--) work();
getchar();getchar();
return 0;
}

最新文章

  1. Java 8函数编程轻松入门
  2. 关于Hadoop的集群环境下虚拟机采用NAT方式连不上网的解决
  3. wordpress取文章时间
  4. js中setInterval与setTimeout用法
  5. Layer弹窗组件
  6. 【转】BAT 延迟变量
  7. JavaScript学习笔记(8)——JavaScript语法之运算符
  8. 再次记录老K站点的工作策略
  9. jquery validate remote验证唯一性
  10. ORA-01940: cannot drop a user that is currently connected解决方法
  11. iOS 好文源码收藏
  12. 【spring源码分析】IOC容器初始化(五)
  13. Fragment与Activity的接口回调
  14. my live health
  15. js签名
  16. 快速排序javascript实现
  17. Delphi如何找到出错行的行数!!
  18. Android Notification和权限机制探讨
  19. WP8.1学习系列(第四章)——交互UX之导航模式
  20. 人活着系列之开会(Floy)

热门文章

  1. ASIHTTPRequest数据压缩
  2. Office 365系列(二) -一些比较容易混淆的概念
  3. Collecting Bugs (概率dp)
  4. 九度OJ 1194:八进制 (进制转换)
  5. Virtualbox报错------> VirtualBox虚拟机下鼠标不正常的解决方法
  6. SpringBoot_集成Shiro后获取当前用户
  7. eclipse安装Activiti Designer插件(转载:http://blog.csdn.net/qq_33547950/article/details/54926435)
  8. R中常用数据挖掘算法包
  9. 3.07课&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;if分支语句
  10. Floyd 学习笔记