bzoj 4500: 矩阵 差分约束系统
2024-09-07 18:53:19
题目:
Description
有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:
- 选择一行, 该行每个格子的权值加1或减1。
- 选择一列, 该列每个格子的权值加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;
}
最新文章
- Java 8函数编程轻松入门
- 关于Hadoop的集群环境下虚拟机采用NAT方式连不上网的解决
- wordpress取文章时间
- js中setInterval与setTimeout用法
- Layer弹窗组件
- 【转】BAT 延迟变量
- JavaScript学习笔记(8)——JavaScript语法之运算符
- 再次记录老K站点的工作策略
- jquery validate remote验证唯一性
- ORA-01940: cannot drop a user that is currently connected解决方法
- iOS 好文源码收藏
- 【spring源码分析】IOC容器初始化(五)
- Fragment与Activity的接口回调
- my live health
- js签名
- 快速排序javascript实现
- Delphi如何找到出错行的行数!!
- Android Notification和权限机制探讨
- WP8.1学习系列(第四章)——交互UX之导航模式
- 人活着系列之开会(Floy)
热门文章
- ASIHTTPRequest数据压缩
- Office 365系列(二) -一些比较容易混淆的概念
- Collecting Bugs (概率dp)
- 九度OJ 1194:八进制 (进制转换)
- Virtualbox报错------> VirtualBox虚拟机下鼠标不正常的解决方法
- SpringBoot_集成Shiro后获取当前用户
- eclipse安装Activiti Designer插件(转载:http://blog.csdn.net/qq_33547950/article/details/54926435)
- R中常用数据挖掘算法包
- 3.07课&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;if分支语句
- Floyd 学习笔记