差分约束系统使用心得及dy引擎分析
来源:互联网 发布:python 兼职 编辑:程序博客网 时间:2024/04/28 18:06
差分约束系统是一个神奇的数与图结合的算法。
如果有一堆又一堆形如:
x1-x2<=k1
x2-x1<=k2
x4-x1<=k3
x4-x2<=k4
……
这样的恶心不等式,我们怎么确定x1-x4的值呢?
这是不可能的,因为我们没有一个确定的量,我们只知道一些数的差。
但是我们可以求出每个数之间的固定的差是多少,前提是给我们的条件只有一组差的解。
这时候差分约束系统便用了用途。
设有x-y<=k,那么我们就给y连一条到x的权值为k的有向边,之后用SPFA跑一个最短路。
如果题目给了我们一些确定的量,我们就把它们放入图中。如果没有给,那么就自己设一个。
很明显可能有负权环,这样的话就有无数组解了。
如果有的点遍历不到,也会有无数组解。
x-y<=k(==)y-x>=-k
我们也可以给x到y连一条权值为-k的有向边,之后跑一个最大路。
如果有正权环也是有无数组解的。
这就是差分约束系统的实现了。
当然题目可不会这么明确地把所有条件给我们,可能有许多隐藏的条件需要自己去发现。
我们来结合实际谈一下。
JZOJ3430
DY引擎
Description
BOSS送给小唐一辆车。小唐开着这辆车从PKU出发去ZJU上课了。
众所周知,天朝公路的收费站超多的。经过观察地图,小唐发现从PKU出发到ZJU的所有路径只会有N(2<=N<=300)个不同的中转点,其中有M(max(0, N-100) <=M<=N)个点是天朝的收费站。N个中转点标号为1…N,其中1代表PKU,N代表ZJU。中转点之间总共有E(E<=50,000)条双向边连接。
每个点还有一个附加属性,用0/1标记,0代表普通中转点,1代表收费站。当然,天朝的地图上面是不会直接告诉你第i个点是普通中转点还是收费站的。地图上有P(1<=P<=3,000)个提示,用[u, v, t]表示:[u, v]区间的所有中转点中,至少有t个收费站。数据保证由所有标记得到的每个点的属性是唯一的。
车既然是BOSS送的,自然非比寻常了。车子使用了世界上最先进的DaxiaYayamao引擎,简称DY引擎。DY引擎可以让车子从U瞬间转移到V,只要U和V的距离不超过L(1<=L<=1,000,000),并且U和V之间不能有收费站(小唐良民一枚,所以要是经过收费站就会停下来交完钱再走)。
DY引擎果然是好东西,但是可惜引擎最多只能用K(0<=K<=30)次。
Input
第一行有6个整数N,M,E,P,L,K分别代表:N个中转点,M个收费站,E条边,P个提示,DY引擎的有效距离L,DY引擎的使用次数K。
接下去E行,每行有3个整数u,v,w(1<=u, v<=N; 1<=w<=1,000,000)表示:u和v之间有一条长度为w的双向边。
接下去P行,每行有3个整数u,v,t(1<=u<=v<=N; 0<=t<=u-v+1)表示: [u, v] 标号区间至少有t个收费站。
Output
输出一个整数,表示小唐从PZU开到ZJU用的最短距离(瞬间转移距离当然是按0来计算的)。
Sample Input
6 2 6 2 5 1
1 2 1
2 3 2
3 6 3
1 4 1
4 5 2
5 6 3
2 5 2
4 6 2
Sample Output
1
【样例解释】
4、5是收费站。1->2(1)->6(1)
对于30%的数据保证:
2<=N<=30,max(0, N-10) <=M<=N,0<=k<=10
对于100%的数据保证:
2<=N<=300,max(0, N-100) <=M<=N,E<=50,000,1<=P<=3,000,1<=L<=1,000,000,0<=K<=30
第一部分求出加油站是哪些中转点:
设p[i]表示中转点1-i的加油站的个数。根据题目给的条件,我们可以列出不等式:
p[u-1]-p[v]<=-t
还有隐藏的条件:
p[i]-p[i-1]<=1,p[i-1]-p[i]<=0
我们给所有的v到u-1连一条权值是-t的边,给i-1到i连一条权值是1的边,给i到i-1连一条权值是0的边。
我们又知道p[n]=m,把n作为起始点,然后SPFA一遍,p[i]-p[i-1]就是i的状态。
第二部分也是SPFA,就是维护的状态多了一点。
Floyed预处理出f[i][j]表示i到j的最短距离,注意当我们枚举k为中转点时,k不能是加油站。因为从i到j间是不能有加油站的。
设d[i][j]表示从1走到i,飞了j次的最短距离。d[1][0]=0。
每次枚举一个点q,一看能否更新d[q][j],用i到q的边维护,相当于普通的SPFA。二看能否更新d[q][j+1],条件是(f[i][q]<=l&&j<=k&&d[i][j]
#include<cstdio>#include<cstring>#define fo(i,x,y) for(int i=x;i<=y;i++)using namespace std;const int maxx=1684300900;int min(int x,int y){return x<y?x:y;}int max(int x,int y){return x>y?x:y;}int i,j,n,m,e,p,l,k,u,v,w,ans=maxx,d1[1000000],d2[301],d[1000000][2],bz[301][301],ff[301][301],fp[301][301],bx[301],f[301][301],t[301][301],dp[301][31],s[301][31];void init();void A();void B();void Floyed();int main(){ init(); A(); Floyed(); B(); fo(i,0,k) ans=min(ans,dp[n][i]); printf("%d\n",ans);}void init(){ memset(f,100,sizeof(f)); memset(ff,100,sizeof(ff)); memset(d2,100,sizeof(d2));d2[0]=0; memset(dp,100,sizeof(dp));dp[1][0]=0; scanf("%d%d%d%d%d%d",&n,&m,&e,&p,&l,&k); fo(i,1,e) { scanf("%d%d%d",&u,&v,&w); f[u][v]=f[v][u]=min(f[v][u],w); if(!bz[u][v]) { bz[u][v]=1; bz[v][u]=1; } } fo(i,1,n)fo(j,1,n)t[i][j]=f[i][j]; fo(i,1,p) { scanf("%d%d%d",&u,&v,&w); if(-w<ff[v][u-1]) ff[v][u-1]=-w; } fo(i,1,n) { if(0<ff[i][i-1]) ff[i][i-1]=0; if(1<ff[i-1][i]) ff[i-1][i]=1; } fo(i,0,n)fo(j,0,n) if(i!=j&&ff[i][j]<maxx) fp[i][++fp[i][0]]=j;}void A(){ d1[1]=n;d2[n]=m;bx[n]=1; i=0;j=1; while(i<j) { i++; int x=d1[i]; fo(q,1,fp[x][0]) { int y=fp[x][q]; if(d2[x]+ff[x][y]<d2[y]) { d2[y]=d2[x]+ff[x][y]; if(!bx[y]) { d1[++j]=y; bx[y]=1; } } } bx[d1[i]]=0; }}void Floyed(){ fo(i,1,n) fo(j,1,n) if(i!=j) fo(k,1,n) if((!(d2[k]-d2[k-1]))&&(i!=k)&&(j!=k)&&(f[i][k]<maxx)&&(f[k][j]<maxx)&&(f[i][k]+f[k][j]<f[i][j])) f[i][j]=f[i][k]+f[k][j];}void B(){ i=0;j=1; d[1][0]=1;d[1][1]=0;s[1][0]=1; while(i<j) { i++; int x=d[i][0],y=d[i][1]; fo(q,2,n) { if(dp[x][y]+t[x][q]<dp[q][y]) { dp[q][y]=dp[x][y]+t[x][q]; if(!s[q][y]) { d[++j][0]=q; d[j][1]=y; s[q][y]=1; } } if(y<k&&f[x][q]<=l&&dp[x][y]<dp[q][y+1]) { dp[q][y+1]=dp[x][y]; if(!s[q][y+1]) { d[++j][0]=q; d[j][1]=y+1; s[q][y+1]=1; } } } s[x][y]=0; }}
- 差分约束系统使用心得及dy引擎分析
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 【差分约束系统】
- 差分约束系统
- 差分约束系统
- 差分约束系统
- ##差分约束系统##
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- proteus 8的一些使用技巧
- cvHoughLines2--- Hough变换
- linux安装JDK
- IOS开发UIBarButtonItem-添加自定义Left或者Right按钮
- Android中采用的MVC框架
- 差分约束系统使用心得及dy引擎分析
- 滑雪
- Eclipse项目转AndroidStudio
- iOS UITextField的边框设置颜色的小坑
- ServletContextListener使用详解
- opencv 通道和深度和图像格式
- myeclipse2014Customize Persperctive失效
- Java PermGen 去哪里了?
- CreateFile第一个参数设备名称