洛谷 [p2294] [HNOI2005] 狡猾的商人
差分约束做法
又是一道转换成前缀和的差分约束题,已知从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] 狡猾的商人的更多相关文章
- 洛谷P2294 [HNOI2005]狡猾的商人
P2294 [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要 ...
- Bzoj1202/洛谷P2294 [HNOI2005]狡猾的商人(带权并查集/差分约束系统)
题面 Bzoj 洛谷 题解 考虑带权并查集,设\(f[i]\)表示\(i\)的父亲(\(\forall f[i]<i\)),\(sum[i]\)表示\(\sum\limits_{j=fa[i]} ...
- 题解——洛谷P2294 [HNOI2005]狡猾的商人(差分约束)
裸的差分约束 dfs判断负环,如果有负环就false,否则就是true 注意有多组数据,数组要清空 #include <cstdio> #include <algorithm> ...
- [luogu P2294] [HNOI2005]狡猾的商人
[luogu P2294] [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据, ...
- P2294 [HNOI2005]狡猾的商人(差分约束)
P2294 [HNOI2005]狡猾的商人 对于每个$(x,y,w)$,连边$(x-1,y,w),(y,x-1,-w)$,表示前$y$个月的收益比前$x-1$个月的收益大$w$ 这样题目就转化为询问图 ...
- LUOGU P2294 [HNOI2005]狡猾的商人(差分约束)
[传送门] (https://www.luogu.org/problemnew/show/P2294) 解题思路 差分约束.先总结一下差分约束,差分约束就是解决一堆不等式混在一起,左边是差的形式,右边 ...
- P2294 [HNOI2005]狡猾的商人
题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断.每组数据的第一行为两个正整数n和m, ...
- [HNOI2005]狡猾的商人 ,神奇做法——贪心
洛谷P2294 [HNOI2005]狡猾的商人 ,神奇做法--贪心 看到大牛都是写的差分约束或带权并查集,本蒟蒻都不太会(还是用差分约束过了的QAQ),但是想出一种贪心的策略,运用神奇的优先队列实现. ...
- [BZOJ1202][HNOI2005]狡猾的商人
[BZOJ1202][HNOI2005]狡猾的商人 试题描述 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i= ...
随机推荐
- HDU--2011
多项式求和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- Oracle_单行函数
Oracle_单行函数 --dual是一张虚拟表,用于做测试 select sysdate from dual; select from dual; 字符函数initcap(),lower(), ...
- git常见操作
本地仓库关联远程仓库 新建本地目录scala git init 这样就新建了一个本地仓库 在远端如github上新建仓库scala 关联远程仓库 git remote add origin git@g ...
- 从CUMT校园导航出现的问题看CSS布局设计(一) CSS盒模型
先说说做的这个校园导航系统值得一提的内容: 1. 二级菜单栏 .iframe内嵌窗口(样式设计.用hover做效果) 2. 高德地图API (自定义底图样式.弹跳点.信息窗体.线路导航) 3. DO ...
- 设置某个类使用或者禁用ARC
设置这个类为ARC的 用:-fobjc-arc 设置这个类非ARC的:-fno-objc-arc 工程是非ARC的,但是引用的第三方类库是ARC的,所以要使用的时候,要单独设置这个第三方的类是A ...
- android项目红色感叹号
Project --> Clean 清理一下,一般要注意的,如果是你的项目文件有错误,特别是xml文件,清理后那个R资源文件会不见的,那就需要你把错误修正后自动生成的.
- get最简单直接粗爆git与github教程
Git是分布式版本控制系统(可以理解为文件管理拓展工具) github一个在线文件托管系统(可以理解为一个在线云盘) 准备工作,在git官网下载git软件件,安装git软件,以windows.为例,下 ...
- 写一个简单的配置文件和日志管理(shell)
最近在做一个Linux系统方案的设计,写了一个之前升级服务程序的配置和日志管理. 共4个文件,服务端一个UpdateServer.conf配置文件和一个UpdateServer脚本,客户端一个Upda ...
- linux libpcap的性能问题,请大家注意绕行。
内核代码中,ip_rcv是ip层收包的主入口函数,该函数由软中断调用.存放数据包的sk_buff结构包含有目的地ip和端口信息,此时ip层进行检查,如果目的地ip不是本机,且没有开启转发的话,则将包丢 ...
- tomcat三种启动不同的启动方式
Linux下tomcat服务的启动.关闭与错误跟踪,通常通过以下几种方式启动关闭tomcat服务: 切换到tomcat主目录下的bin目录 1. 启动tomcat服务 方式一:直接启动 ./start ...