【JZOJ3430】DY引擎
来源:互联网 发布:sql server bi 编辑:程序博客网 时间:2024/05/16 01:44
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 2Sample Output
1
【样例解释】
4、5是收费站。1->2(1)->6(1)
Data Constraint
对于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
Solution
首先分析一下题目,首先收费站和别的问题是完全分开的,所以我们先求解收费站。
设
有n个变量,P个形如
这里用到了差分约束系统,不懂得可以去看一下。
这里简单介绍求解的方法:
首先整理一下不等式:
还有隐藏的不等式:
于是,我们把
这样,第一个问题就解决了。
第二个问题让我们求使用k次引擎
那么有了第一问的条件,我们可以求出两点之间的最短路。
对于求解有很多方法,这里不一一介绍:
我们设
最后答案为
Code
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 301using namespace std;int n,m,E,P,L,K;int d[N];int b[N][N];bool vis[N],s[N];int f[N][N];int dp[N][31];int dl[N*N];int bs[N*N];bool bz[N][31];void find(){ int l=0,r=1; memset(d,60,sizeof(d)); dl[1]=n; d[n]=m; d[0]=0; vis[n]=true; while(l<r) { l++; int x=dl[l]; fo(i,1,n) if(d[x]+b[x][i]<d[i]) { d[i]=d[x]+b[x][i]; if(!vis[i]) { vis[i]=true; dl[++r]=i; } } vis[x]=false; }}void spfa(){ int l=0,r=1; memset(dp,60,sizeof(dp)); memset(dl,0,sizeof(dl)); memset(bs,60,sizeof(bs)); dp[1][0]=0; dl[1]=1; bs[1]=0; vis[1]=true; while(l<r) { l++; int x=dl[l],t=bs[l]; fo(i,1,n) if(i!=x) { if(dp[x][t]+f[x][i]<dp[i][t]) { dp[i][t]=dp[x][t]+f[x][i]; if(!bz[i][t]) { bz[i][t]=true; r++; dl[r]=i; bs[r]=t; } } if(t<K && f[x][i]<=L && dp[i][t+1]>dp[i][t]) { dp[i][t+1]=dp[x][t]; if(!bz[i][t+1]) { bz[i][t+1]=true; r++; dl[r]=i; bs[r]=t+1; } } } bz[x][t]=false; }}int main(){ freopen("3430.in","r",stdin); freopen("3430.out","w",stdout); cin>>n>>m>>E>>P>>L>>K; memset(f,60,sizeof(f)); fo(i,1,E) { int u,v,w; scanf("%d %d %d",&u,&v,&w); f[u][v]=f[v][u]=min(f[u][v],w); } fo(i,1,n) f[i][i]=0; memset(b,60,sizeof(b)); fo(i,1,P) { int u,v,w; scanf("%d %d %d",&u,&v,&w); b[v][u-1]=min(b[v][u-1],-w); } fo(i,1,n) b[i][i-1]=0,b[i-1][i]=1; find(); fo(i,1,n) s[i]=d[i]-d[i-1]; int tttt=0; fo(k,1,n) if(!s[k]) { fo(i,1,n) fo(j,1,n) if(i!=j && i!=k && k!=j) f[i][j]=min(f[i][j],f[i][k]+f[k][j]); } spfa(); int ans=2147483647; fo(i,0,K) ans=min(ans,dp[n][i]); cout<<ans;}
- [JZOJ3430] DY引擎
- 【JZOJ3430】DY引擎
- 【NOIP2013模拟】DY引擎
- 【JZOJ 3430】DY引擎
- 【JZOJ 3430】 DY引擎
- 【NOIP2013模拟】DY引擎
- NOIP2013模拟】DY引擎 题解+代码
- 差分约束系统使用心得及dy引擎分析
- DY同志的简历
- 初遇Worm.Viking.dy
- Hibernate中dynamic-insert和dy...
- 使用powershell Client进行有效dy
- 陈dy学姐教师招聘经验
- 微分dx、dy是无穷小吗?
- C++的类型转换符:static_cast、dy…
- 关于丢番图方程x^2-dy^2=-1
- 风车——ctx.rotate(angle),ctx.translate(dx, dy)
- 股票入门基础知识21:什么是股息收益率(DY)
- 双向循环链表
- Activity创建流程
- Codeforces Round #355D (Div. 2) 暴力+BFS
- cocos2d-x Sprite::create(“filename.png”) returning null
- Maximal Square
- 【JZOJ3430】DY引擎
- ubuntu nameserver 127.0.1.1
- JavaScript跨域总结与解决办法
- sed命令--shell脚本
- html5 ios中忽略将数字变为电话号码
- 数据库设计准则(第一、第二、第三范式说明)
- 数据库设计的一些心得与经验
- HTML5页面渲染性能的”程序转换“思路
- MySQL集群的可行方案