差分约束做法

又是一道转换成前缀和的差分约束题,已知从s月到t月的收入w,设数组pre[i]代表从开始到第i个月的总收入

构造差分不等式 $ pre[s-1]-pre[t]==w $

为了满足松弛操作,我们将不等式转化成 $ pre[s-1]-pre[t]>=w $

这样建图以后我们发现当且仅当图中出现正环或负环时,账本为假,

我们可以直接在建图时加入一条反向的权值相反的边,这样直接判断负环即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define RST(a) memset((a),0,sizeof((a)))
using namespace std;
int init(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return fh*rv;
}
int T,head[10005],nume,dis[10005];
bool f[10005];
struct edge{
int to,nxt,dis;
}e[10005];
void adde(int from,int to,int dis){
e[++nume].to=to;
e[nume].dis=dis;
e[nume].nxt=head[from];
head[from]=nume;
}
bool dfs_SPFA(int u){
f[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(dis[v]>dis[u]+e[i].dis){
dis[v]=dis[u]+e[i].dis;
if(f[v]) return 1;
if(dfs_SPFA(v)) return 1;
}
}
f[u]=0;
return 0;
}
int main(){
freopen("in.txt","r",stdin);
T=init();
while(T--){
RST(dis);RST(head);RST(e);nume=0;RST(f);
int n=init(),m=init();
for(int i=1;i<=m;i++){
int u=init(),v=init(),di=init();
adde(u-1,v,di);
adde(v,u-1,-di);
}
bool fff=0;
for(int i=0;i<=n;i++){
if(dfs_SPFA(i)) {fff=1;break;}
}
if(fff) printf("false\n");
else printf("true\n");
}
fclose(stdin);
return 0;
}

并查集做法

本题也可以维护一个带权并查集,

fa[i]表示i号元素的父亲节点,root[i]表示i所在并查集的代表元,dis[i]=pre[i]-pre[root[i]]。所以我们可以维护一个带权并查集。

并查集的两个关键操作,查询和合并

find:

带权并查集的一般写法,更新父节点时,一并更新dis[].

因为原来\(dis[x]=pre[x]-pre[fa[x]]\),更新后\(dis[fa[x]]=pre[fa[x]]-pre[root[x]]\),所以 \(dis[x]+=dis[fa[x]]\)就更新完成了。

merge

如果读入的两个点在同一个并查集中,判断dis[u-1]-dis[v]是否等于w,若不等于,则为假。

如果不在同一个并查集中,使\(fa[root[u-1]]=root[v]\).

注意,此处为了保证合并以后原有的数量关系不发生改变,要注意 dis[root[u-1]]更新的时候加上的数值,可以在本上画一下。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define RST(a) memset((a),0,sizeof((a)))
using namespace std;
int init(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return fh*rv;
}
int T,fa[10005],dis[10005];
int find(int x){
if(fa[x]!=x){
int t=find(fa[x]);
dis[x]+=dis[fa[x]];
fa[x]=t;
}
return fa[x];
}
int main(){
freopen("in.txt","r",stdin);
T=init();
while(T--){
bool fff=0;
RST(fa);RST(dis);
int n=init(),m=init();
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
int u=init(),v=init(),w=init();
int r1=find(u-1),r2=find(v);
if(r1==r2){
if(!fff&&dis[v]-dis[u-1]!=w) fff=1,printf("false\n");
}else{
fa[r1]=r2;
dis[r1]=dis[v]-dis[u-1]-w;
}
}
if(!fff) printf("true\n");
}
fclose(stdin);
return 0;
}

洛谷 [p2294] [HNOI2005] 狡猾的商人的更多相关文章

  1. 洛谷P2294 [HNOI2005]狡猾的商人

    P2294 [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要 ...

  2. Bzoj1202/洛谷P2294 [HNOI2005]狡猾的商人(带权并查集/差分约束系统)

    题面 Bzoj 洛谷 题解 考虑带权并查集,设\(f[i]\)表示\(i\)的父亲(\(\forall f[i]<i\)),\(sum[i]\)表示\(\sum\limits_{j=fa[i]} ...

  3. 题解——洛谷P2294 [HNOI2005]狡猾的商人(差分约束)

    裸的差分约束 dfs判断负环,如果有负环就false,否则就是true 注意有多组数据,数组要清空 #include <cstdio> #include <algorithm> ...

  4. [luogu P2294] [HNOI2005]狡猾的商人

    [luogu P2294] [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据, ...

  5. P2294 [HNOI2005]狡猾的商人(差分约束)

    P2294 [HNOI2005]狡猾的商人 对于每个$(x,y,w)$,连边$(x-1,y,w),(y,x-1,-w)$,表示前$y$个月的收益比前$x-1$个月的收益大$w$ 这样题目就转化为询问图 ...

  6. LUOGU P2294 [HNOI2005]狡猾的商人(差分约束)

    [传送门] (https://www.luogu.org/problemnew/show/P2294) 解题思路 差分约束.先总结一下差分约束,差分约束就是解决一堆不等式混在一起,左边是差的形式,右边 ...

  7. P2294 [HNOI2005]狡猾的商人

    题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断.每组数据的第一行为两个正整数n和m, ...

  8. [HNOI2005]狡猾的商人 ,神奇做法——贪心

    洛谷P2294 [HNOI2005]狡猾的商人 ,神奇做法--贪心 看到大牛都是写的差分约束或带权并查集,本蒟蒻都不太会(还是用差分约束过了的QAQ),但是想出一种贪心的策略,运用神奇的优先队列实现. ...

  9. [BZOJ1202][HNOI2005]狡猾的商人

    [BZOJ1202][HNOI2005]狡猾的商人 试题描述 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i= ...

随机推荐

  1. UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

    最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...

  2. 数学3(博弈+splya)

    数学3(博弈+splya) 标签: 数学 hdu_5194 (打表找规律) 题意 有n和黑球和m个白球,现在一个个的取出这些球,如果是黑球则当前标记为1,白球为0,那么当取完这些球会得到一些序列.问你 ...

  3. hdu_3068 最长回文(Manacher算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others)    M ...

  4. linux基本命令学习02

    =============================================================================a.txtc:\abc\a.txt windo ...

  5. GO开发[四]:golang函数

    函数 1.声明语法:func 函数名 (参数列表) [(返回值列表)] {} 2.golang函数特点: a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个 ...

  6. [国嵌攻略][127][tty驱动程序架构]

    tty概念解析 在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备. 1.串口终端(/dev/ttyS*) 串口终端是使用计算机串口连接的终端设备.Lin ...

  7. Hibernate查询对象的方法浅析

    Hibernate 查询对象是根据对象的id查询的,只要你有id (id唯一),则无论你是否其他字段与传过来的对象一致,都会查到该id在数据库对应的对象.若是在关联查询中,所关联表的id为空,即所查表 ...

  8. 微信小程序 PHP后端form表单提交实例详解

    微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...

  9. OKMX6Q LTIB编译

    因为在16.04上编译有许多解决不了的错误,最后还是在飞凌的12.04虚拟机上编译的. 按照手册<OKMX6X-S2-LTIB编译手册-V1.1-2016-08-18>进行到第8步时,出现 ...

  10. Java Reflection 反射基础

    反射基础: package reflection; /** * Created by : Infaraway * DATE : 2017/3/2 * Time : 23:06 * Funtion : ...