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. CCCC 月饼

    https://www.patest.cn/contests/gplt/L2-003 题解:按平均值贪心. 坑:有一个样例卡住了,是因为 while (i<=n&&x - bs[ ...

  2. 大数据智能SOC解决方案

  3. requests库的post请求

    requests库的post请求 #coding:utf-8 import requests import json class Trans(object): def __init__(self, w ...

  4. 【查阅】mysql系统视图查看

    [1]查看表大小 SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name', table_rows AS 'Number of Rows', ...

  5. 配合dedecms内容模型实现后台输入栏目id前端输出文章列表

    为了简化开发的工作量,也方便编辑快速操作,决定将后台进行重新设置.配合dedecms内容模型实现后台输入栏目id前端输出文章列表,这样制作科室专题页也变快了很多.比如,我们添加一个“科室专家栏目id” ...

  6. iOS开发-url包括中文报错解决的方法

    常常, 我们用通过这个方案调用API. NSString* urlString = [NSString stringWithFormat:@"http://api.douban.com/v2 ...

  7. Linuxer-&quot;Linux开发人员自己的媒体&quot;第五月稿件和赠书名单

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/juS3Ve/article/details/78859630 Linuxer已经从一个单纯的读者服务 ...

  8. Tomcat项目部署的三种方法

    第一种方法如下:直接把我们的项目文件夹放到tomcat里面,在这里我自己做的是一个测试项目oa,如图 启动tomcat,打开浏览器,输入localhost/oa  即可打开你的文件,注意 :访问的时候 ...

  9. HTML5插件

    HTML 助手(插件) 辅助应用程序(helper application)是可由浏览器启动的程序.辅助应用程序也称为插件. 辅助程序可用于播放音频和视频(以及其他).辅助程序是使用 <obje ...

  10. 用Python实现的数据结构与算法:开篇

    一.概述 用Python实现的数据结构与算法 涵盖了常用的数据结构与算法(全部由Python语言实现),是 Problem Solving with Algorithms and Data Struc ...