hdu1201,hdu6252差分约束系统
差分约束系统一般用来解决a-b>=c的问题,有n个这样的限制条件,求出某个满足这些条件的解
可以将这个问题转化成最长路问题,即b到a的距离最少为c,而有多条b到a的路的话,我们就取最长的b到a的距离。
将限制条件转化成为一条边,然后求最长路,一般解决最长路问题,我们使用的算法是spfa
入门题 hdu1201
题意:有n个限制条件,区间a到b至少是有c个点,求满足条件的最少端点数
分析:需要满足所有条件,那么首先想到的是差分约束系统。先定义数组G,Gi为0到i有Gi个端点,那么条件a到b区间至少有c个端点可以转化成,Gb-G(a-1)>=c
,显然n个限制条件是不够的,还需要满足1>=G(i+1)-G(i)>=0,转化为,G(i+1)-G(i)>=0和G(i-1)-G(i)>=-1,用这些边构造一个图,然后G(max)即为答案
由于边的数量比较多,用vector构图的话会超时,所以用邻接表加spfa
ac代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 50000+10;
int f[maxn],nex[maxn*3],w[maxn*3],to[maxn*3],cnt;
void add(int x,int y,int k)
{
cnt++;
w[cnt]=k;
to[cnt]=y;
nex[cnt]=f[x];
f[x]=cnt;
}
bool vis[maxn];
int dis[maxn]; int spaf()
{
for(int i=0;i<maxn;i++)dis[i]=-1;
queue<int>que;
que.push(0);
vis[0]=1;
dis[0]=0;
while(que.size())
{
// for(int i=0;i<=13;i++)cout<<dis[i]<<" ";cout<<endl; int x=que.front();
que.pop();
vis[x]=0;
// cout<<x<<endl;
for(int i=f[x];i;i=nex[i])
{
// cout<<to[i]<<" ";
if(dis[x]+w[i]>dis[to[i]])
{
dis[to[i]]=dis[x]+w[i];
if(vis[to[i]]==0)
{
vis[to[i]]=1;
que.push(to[i]);
}
}
}
// cout<<endl;
} }
int main()
{
int n;
cin>>n;
for(int i=0;i<maxn;i++)f[i]=0; for(int i=1;i<=n;i++)
{
int x,y,w;
scanf("%d %d %d",&x,&y,&w);
add(x,y+1,w);
}
for(int i=1;i<=50000+1;i++)
{
add(i-1,i,0);
add(i,i-1,-1);
}
spaf();
printf("%d\n",dis[50000+1]);
return 0;
}
提升题 hdu6252
题意:给出的也是限制条件,但是也需要注意一个限制条件,dis[i]-dis[i-1]>0
ac代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=2005;
int f[maxn],w[maxn*3],to[maxn*3],nex[maxn*3];
bool vis[maxn];
int out[maxn],cnt=0,dis[maxn],n,m,k;
void add(int a,int b,int c)
{
cnt++;
w[cnt]=c;
to[cnt]=b;
nex[cnt]=f[a];
f[a]=cnt;
}
bool spfa()
{
for(int i=1; i<maxn; i++)dis[i]=-1,vis[i]=0,out[i]=0;
queue<int>que;
que.push(1);
vis[1]=1;
dis[1]=0;
while(que.size())
{
// for(int i=1;i<=n;i++)printf(" %d",dis[i]);cout<<endl;
int x=que.front();
// cout<<x<<"out"<<endl;
vis[x]=0;
que.pop();
out[x]++;
if(out[x]>n)
return false;
for(int i=f[x]; i; i=nex[i])
{
// cout<<to[i]<<"to"<<endl;
if(dis[x]+w[i]>dis[to[i]])
{
dis[to[i]]=dis[x]+w[i];
if(vis[to[i]]==0)
{
que.push(to[i]);
vis[to[i]]=1;
}
}
}
}
return true;
}
int main()
{
int T;
cin>>T;
for(int cn=1; cn<=T; cn++)
{
cnt=0;
scanf("%d %d %d",&n,&m,&k);
for(int i=1; i<maxn; i++)f[i]=0;
for(int i=2; i<=n; i++)
add(i-1,i,1);
for(int i=1; i<=m; i++)
{
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
if(a==b&&c==d)
{
add(b,c,k);
add(c,b,-k);
}
else
{
add(c,b,1-k);
add(a,d,k+1);
}
}
if(spfa())
{
printf("Case #%d:",cn);
for(int i=2;i<=n;i++)
printf(" %d",dis[i]-dis[i-1]);
cout<<endl;
}
else
printf("Case #%d: IMPOSSIBLE\n",cn);
}
return 0;
}
总结:
1.如果给出的是a-b>c,我们可以转化为,a-b>=c+1
2.如果给出的是a-b<=c,我们可以转化为,b-a>=-c
3.对于a-b>=c,我们可以构成b到a距离为c的边,然后构成图,求最长路
4.对于a-b<=c,我们可以构成b到a距离为c的边,然后构成图,求最短路
5.如果这些限制条件存在矛盾,即没有合法的答案时,图会存在回路,只需要判断某个点出队次数超过n次,直接返回false
6.一般情况,题目会存在一些隐含的限制条件,需要我们推理出来
hdu1201,hdu6252差分约束系统的更多相关文章
- UVA11478 Halum [差分约束系统]
https://vjudge.net/problem/UVA-11478 给定一个有向图,每条边都有一个权值.每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的 ...
- BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5395 Solved: 1750[Submit][Status ...
- ACM/ICPC 之 差分约束系统两道(ZOJ2770-POJ1201)
当对问题建立数学模型后,发现其是一个差分方程组,那么问题可以转换为最短路问题,一下分别选用Bellmanford-SPFA解题 ZOJ2770-Burn the Linked Camp //差分约束方 ...
- POJ1201 Intervals(差分约束系统)
与ZOJ2770一个建模方式,前缀和当作点. 对于每个区间[a,b]有这么个条件,Sa-Sb-1>=c,然后我就那样连边WA了好几次. 后来偷看数据才想到这题还有两个隐藏的约束条件. 这题前缀和 ...
- UVA 11374 Halum (差分约束系统,最短路)
题意:给定一个带权有向图,每次你可以选择一个结点v 和整数d ,把所有以v为终点的边权值减少d,把所有以v为起点的边权值增加d,最后要让所有的边权值为正,且尽量大.若无解,输出结果.若可无限大,输出结 ...
- Burn the Linked Camp(bellman 差分约束系统)
Burn the Linked Camp Time Limit: 2 Seconds Memory Limit: 65536 KB It is well known that, in the ...
- zoj 2770 Burn the Linked Camp (差分约束系统)
// 差分约束系统// 火烧连营 // n个点 m条边 每天边约束i到j这些军营的人数 n个兵营都有容量// Si表示前i个军营的总数 那么 1.Si-S(i-1)<=C[i] 这里 建边(i- ...
- POJ 3169 Layout (差分约束系统)
Layout 题目链接: Rhttp://acm.hust.edu.cn/vjudge/contest/122685#problem/S Description Like everyone else, ...
- POJ 3169 Layout 差分约束系统
介绍下差分约束系统:就是多个2未知数不等式形如(a-b<=k)的形式 问你有没有解,或者求两个未知数的最大差或者最小差 转化为最短路(或最长路) 1:求最小差的时候,不等式转化为b-a>= ...
随机推荐
- 前后端分离djangorestframework——序列化与反序列化数据
我们写好后端的代码,要把数据交给前端的展示的,这个数据以什么类型给前端呢?学到这里,我们已经知道这个数据最好是json字符串才行,因为网络间的传输,只认字符串或者二进制,字符串就是我们的数据,二进制就 ...
- SQL Server最大内存设为0后的处置办法
故障说明: 远程调整实例内存时疏忽,将实例最大内存调整为了0,因此最大内存变成了128MB的最小值. 解决方式: 1.正常关闭SQL Server服务,如果是集群,需要先关停止集群角色防止故障转移,然 ...
- Vmware ESXi日志文件存放目录地址
有时候我们需要查看虚拟服务端突然宕机的原因,就需要来查看这些日志 ESXi 通过使用 syslog 功能,在日志文件中记录主机活动. 组件 位置 用途 VMkernel /var/log/vmkern ...
- kafka_2.11-2.0.0_介绍
1. JMS是什么 1.1. JMS的基础 JMS是什么:JMS是Java提供的一套技术规范 JMS干什么用:用来异构系统 集成通信,缓解系统瓶颈,提高系统的伸缩性增强系统用户体验,使得系统模块化和组 ...
- linux下的文件目录结构
linux的文件系统是采用层级式的树状目录结构,在此结构中的最上层是根目录“/”,然后在此目录下再创建其他的目录 - root,存放root用户的相关文件 - home,存放普通用户的相关文件 - b ...
- sqlite线程模式的设置
(1)编译阶段 这几种模式可以通过参数SQLITE_THREADSAFE在编译阶段指定,可以取值0,1,2,默认是1.这三种取值的含义如下: 0:单线程模式,即内部不做mutex保护,多线程运行sql ...
- [tool] AI视频翻译 解决英文视频字幕问题(类似youtube自动生成字幕)
1.网易见外是网易人工智能事业部旗下的AI视频翻译产品. 字幕支持手工编辑和下载 不过网易见外 只支持WEB在线操作 并且只支持单个上传操作 目前没有客户端 2.人人译视界 (IOS 安卓 PC客户端 ...
- 强化学习(三)—— 时序差分法(SARSA和Q-Learning)
1.时序差分法基本概念 虽然蒙特卡洛方法可以在不知道状态转移概率矩阵的前提下,灵活地求解强化学习问题,但是蒙特卡洛方法需要所有的采样序列都是完整的状态序列.如果我们没有完整的状态序列就无法用蒙特卡洛方 ...
- Python:Day26 socket
SOCKET通信流程 服务器创建套接字链接: 1.创建SOCKET,socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=No ...
- Nginx缓存服务
Nginx缓存服务 1.缓存常见类型 2.缓存配置语法 3.缓存配置实践 4.缓存清理实践 5.部分页面不缓存 6.缓存日志记录统计 通常情况下缓存是用来减少后端压力, 将压力尽可能的往前推, 减少后 ...