P4578 [FJOI2018]所罗门王的宝藏

错解:

设第$i$行上的值改变了$r1[i]$,第$j$列上的值改变了$r2[i]$

显然密码$(i,j,c)=r1[i]+r2[j]$

对于同一列上的两个密码$(i_{1},j,c_{1}),(i_{2},j,c_{2})$,它们的差值即为$c_{1}-c_{2}=r1[i_{1}]-r1[i_{2}]$

同一行上的同理。

这样我们就可以确定$r1[i],r2[j]$之间的关系,并以此判断

那么对于每组数据,我们可以$O(k^2)$两两枚举宝石,用上述方法判断即可。

同一个地方可能有两颗宝石

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
void read(int &x){
char c=getchar();x=;bool f=;
while(!isdigit(c)) f=(f&&c!='-'),c=getchar();
while(isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
x=f?x:-x;
}
#define N 1005
int n,m,k,x[N],y[N],v[N],d1[N][N],d2[N][N];
bool w1[N][N],w2[N][N],ok;
int ask(int i,int j,int c){
if(c) return y[i]<y[j]?v[i]-v[j]:v[j]-v[i];
else return x[i]<x[j]?v[i]-v[j]:v[j]-v[i];
}
bool check(int i,int j){
if(x[i]==x[j]&&y[i]==y[j]&&v[i]!=v[j]) return ;//同个位置两颗宝石
if(y[i]==y[j]){
if(w1[x[i]][x[j]]&&d1[x[i]][x[j]]!=ask(i,j,)) return ;
d1[x[i]][x[j]]=d1[x[j]][x[i]]=ask(i,j,);
w1[x[i]][x[j]]=w1[x[j]][x[i]]=;
}
if(x[i]==x[j]){
if(w2[y[i]][y[j]]&&d2[y[i]][y[j]]!=ask(i,j,)) return ;
d2[y[i]][y[j]]=d2[y[j]][y[i]]=ask(i,j,);
w2[y[i]][y[j]]=w2[y[j]][y[i]]=;
}return ;
}
int main(){
int T;read(T);
while(T--){
memset(d1,,sizeof(d1));
memset(d2,,sizeof(d2));
memset(w1,,sizeof(w1));
memset(w2,,sizeof(w2));
read(n);read(m);read(k);ok=;
for(int i=;i<=k;++i)
read(x[i]),read(y[i]),read(v[i]);
for(int i=;i<=k&&ok;++i)
for(int j=i+;j<=k&&ok;++j)
ok=check(i,j);
printf(ok?"Yes\n":"No\n");
}return ;
}

上面这个做法被评论hack了

今天终于用差分约束过掉了

发现对于$(x1,y1,w1),(x2,y2,w2)$

如果$x1==x2$,那么可以得到$y1,y2$之间的操作差值$v[y1]-v[y2]=w1-w2$

于是通过这样在行和列分别建图

跑spfa判负环

记住多组数据,该清空的全清空掉

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1005
#define M 2000005
int T,n,m,k,u[N],v[N],w[N],f1[N],f2[N];
bool vis1[N],vis2[N],ok; int Cnt1,hd1[N],nxt1[M],ed1[N],poi1[M],val1[M];
void adde1(int x,int y,int v){
nxt1[ed1[x]]=++Cnt1; hd1[x]=hd1[x]?hd1[x]:Cnt1;
ed1[x]=Cnt1; poi1[Cnt1]=y; val1[Cnt1]=v;
}
void link1(int x,int y,int v){adde1(x,y,v),adde1(y,x,-v);} int Cnt2,hd2[N],nxt2[M],ed2[N],poi2[M],val2[M];
void adde2(int x,int y,int v){
nxt2[ed2[x]]=++Cnt2; hd2[x]=hd2[x]?hd2[x]:Cnt2;
ed2[x]=Cnt2; poi2[Cnt2]=y; val2[Cnt2]=v;
}
void link2(int x,int y,int v){adde2(x,y,v),adde2(y,x,-v);} void spfa1(int x){
if(vis1[x]) ok=;
if(ok) return ;
vis1[x]=;
for(int i=hd1[x];i&&!ok;i=nxt1[i]){
int to=poi1[i];
if(f1[to]>f1[x]+val1[i])
f1[to]=f1[x]+val1[i],spfa1(to);
}
vis1[x]=;
}
void spfa2(int x){
if(vis2[x]) ok=;
if(ok) return ;
vis2[x]=;
for(int i=hd2[x];i&&!ok;i=nxt2[i]){
int to=poi2[i];
if(f2[to]>f2[x]+val2[i])
f2[to]=f2[x]+val2[i],spfa2(to);
}
vis2[x]=;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
f1[]=f2[]=ok=;
for(int i=;i<=n;++i) f1[i]=2e9;
for(int i=;i<=m;++i) f2[i]=2e9;
for(int i=;i<=n;++i) adde1(,i,);//虚拟源点建图,防止图不连通
for(int i=;i<=m;++i) adde2(,i,);
for(int i=;i<=k;++i){
scanf("%d%d%d",&u[i],&v[i],&w[i]);
for(int j=i-;j;--j){
if(v[i]==v[j]) link1(u[i],u[j],w[j]-w[i]);
if(u[i]==u[j]) link2(v[i],v[j],w[j]-w[i]);
}
}
spfa1(); spfa2();
puts(ok?"No":"Yes");
for(int i=;i<=n;++i) vis1[i]=hd1[i]=ed1[i]=;
for(int i=;i<=m;++i) vis2[i]=hd2[i]=ed2[i]=;
for(int i=;i<=Cnt1;++i) nxt1[i]=poi1[i]=;
for(int i=;i<=Cnt2;++i) nxt2[i]=poi2[i]=;
Cnt1=Cnt2=;
}return ;
}

bzoj5470 / P4578 [FJOI2018]所罗门王的宝藏的更多相关文章

  1. 【BZOJ5470】[FJOI2018]所罗门王的宝藏()

    [BZOJ5470][FJOI2018]所罗门王的宝藏() 题面 BZOJ 洛谷 有\(n+m\)个变量,给定\(k\)组限制,每次告诉你\(a_i+b_j=c_k\),问是否有可行解. 题解 一道很 ...

  2. 洛谷P4578 [FJOI2018]所罗门王的宝藏(dfs)

    题意 题目链接 Sol 对于每个询问\(x, y, c\) 从在\((x, y)\)之间连一条边权为\(c\)的双向边,然后就是解\(K\)个二元方程. 随便带个数进去找找环就行了 #include& ...

  3. P4578 [FJOI2018]所罗门王的宝藏

    传送门 考虑一个位置答案传递性,如果某个位置的红宝石转动确定了,那么会引起连锁反应: 如图,绿色的转动确定了,那么那两个蓝色的转动也确定了 自己手玩一下,发现如果有解那么随便找一个开始然后一路玩下去最 ...

  4. 洛谷4578 & LOJ2520:[FJOI2018]所罗门王的宝藏——题解

    https://www.luogu.org/problemnew/show/P4578 https://loj.ac/problem/2520 有点水的. 先转换成图论模型,即每个绿宝石,横坐标向纵坐 ...

  5. luoguP4578_ [FJOI2018]所罗门王的宝藏

    题意 一个n*m的矩阵,初始值全为0,每一行每一列操作一次可以加1或者减1,问能否操作得到给定矩阵. 分析 行和列的分别的加减是可以相互抵消的,因此我们只需要考虑行的加和列的减. 对于给定矩阵每一个数 ...

  6. 题解【[FJOI2018]所罗门王的宝藏】

    本题解同步于luogu emmm切了近年省选题来写题解啦qwq 该题较其他省选题较水吧(否则我再怎么做的出来 思路是图论做法,做法上楼上大佬已经讲的很清楚了,我来谈谈代码实现上的一些细节 \[\tex ...

  7. 【LOJ】 #2520. 「FJOI2018」所罗门王的宝藏

    题解 发现似乎相当于问一个2000个元的方程组有没有解-- 然而我懵逼啊-- 发现当成图论,两个点之间连一条边,开始BFS,每个点的值赋成边权减另一个点的点权 如果一个环不合法那么肯定无解 代码 #i ...

  8. yyb省选前的一些计划

    突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...

  9. [FJOI2018]所罗门的宝藏

    大概是最后一篇题解,其实只是想颓废一下打个故事 据古代传说记载,所罗门王即是智慧的代表,又是财富的象征.他建立了强大而富有的国家,聚集了大批的黄金象牙和钻石,并把这些价值连城的珍宝藏在一个神秘的地方, ...

随机推荐

  1. Java-06-动手动脑

    1.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 因为子类继承于父类,子类中有父类的对象,父类的构造方法初始化后,子类才能运行自己的构造方法 不能放过来,继 ...

  2. ubuntu14.04下编译支持opengl的opencv

    在学习基于opencv的AR时,编译程序遇到报错,发现opencv不支持opengl.网上原因得知,在编译opencv时,opencv2.4以后的版本中默认ENABLE_OPENGL = NO,只需要 ...

  3. Ubuntu下更改Vim配置文件打造C/C++风格

    转载:Ubuntu下更改Vim配置文件打造C/C++风格 Vim默认的配置使用起来还不能让人满意,还需要自己配置 默认配置文件是:/etc/vim/vimrc我们可以在家目录下建立自己的配置文件切换到 ...

  4. opencv之Mat数据类型

    data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data) dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维 c ...

  5. hadoop的两类配置文件及3种启动/关闭方式

    hadoop配置文件 默认配置文件:四个模块相对应的jar包中:$HADOOP_HOME/share/hadoop        *core-default.xml        *hdfs-defa ...

  6. iOS多线程编程之GCD介绍(转载)

    一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 GCD是苹果公司为多核的并行运算提 ...

  7. 优云软件助阵GOPS·2017全球运维大会北京站

    GOPS· 2017全球运维大会北京站于2017年7月28日-29日在北京隆重举办,汇聚国内一线运维专家和诸多运维同仁达800余名.作为长期致力于企业级高端运维市场软件开发和咨询服务的优云软件受邀参与 ...

  8. 前端 HTML文档 详解

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. dedecms自增标签[field:global.autoindex/]的运用

    用bootstrap建站时用到幻灯片切换模块,里面有个active(下面代码中的data-slide-to="0"),其余的按顺序递增(1,2),如果用dedecms就可以用aut ...

  10. quic协议实时视频直播

    扫盲 https://www.jianshu.com/p/b7546ff9b683 demo https://github.com/felix-001/QuicRtmp https://github. ...