【JZOJ5430】【NOIP2017提高A组集训10.27】图
来源:互联网 发布:淘宝上卖的龙钞真假 编辑:程序博客网 时间:2024/05/16 14:04
Description
有一个n个点的无向图,给出m条边,每条边的信息形如< x,y,c,r>给出q组询问形如< u,v,l,r>接下来解释询问以及边的意义询问表示,一开始你在点u上,然后按顺序处理编号从l到r的边对于一条边< x,y,c,r>,你可以进行两种操作:
如果你当前在x点或者y点上,那么你可以走这条边(从x到y或从y到x)并付出c的代价(当然你也可以不走,看操作2)
如果你不走这条边或者不可以走这条边(即你当前不在x或y上),那么你需要付出r的代价询问如果要从u点开始,按顺序处理完编号从l到r的边之后到达v点的最小代价,如果不能到达v,那么输出-1。
边和点的编号从1开始。
Data Constraint
对于20%的数据,n<=10,m<=1000,q<=1000
对于40%的数据,n<=10,m<=10000,q<=30000
对于60%的数据,n<=20,m<=10000,q<=30000
对于80%的数据,n<=25,m<=10000,q<=200000
对于100%的数据,n<=30,m<=20000,q<=200000
Solution
分治。mid左边设l[x][y][z]表示x~mid中从y开始z结束的最短路。mid右边设r[x][y][z]表示mid+1~x中从y开始z结束的最短路。更新一次是O(N^2)的。对于跨过mid的询问直接枚举中间点更新即可。时间复杂度O(n^2mlogm+n*q)。
Code
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int maxn=2e5+5,maxn1=2e4+5;struct code{ int x,y,z,k,id;}q[maxn],a[maxn],d[maxn];int f[maxn1][31][31],b[maxn];int n,m,qq,i,t,j,k,x,y,z;void dg(int l,int r,int x,int y){ if (x>y) return; if (l==r){ if (a[l].x>a[l].y) swap(a[l].x,a[l].y); for (i=x;i<=y;i++){ b[q[i].id]=1e9; if (q[i].x>q[i].y) swap(q[i].x,q[i].y); if (q[i].x==a[l].x && q[i].y==a[l].y) b[q[i].id]=a[l].z; if (q[i].x==q[i].y) b[q[i].id]=min(b[q[i].id],a[l].k); } return; } int mid=(l+r)/2,mi,mx; memset(f[mid],127,sizeof(f[mid])); f[mid][a[mid].y][a[mid].x]=f[mid][a[mid].x][a[mid].y]=a[mid].z; for (i=1;i<=n;i++) f[mid][i][i]=min(a[mid].k,f[mid][i][i]); for (i=mid-1;i>=l;i--){ for (j=1;j<=n;j++) for (k=1;k<=n;k++) f[i][j][k]=f[i+1][j][k]+a[i].k; for (j=1;j<=n;j++)f[i][a[i].y][j]=min(f[i][a[i].y][j],f[i+1][a[i].x][j]+a[i].z); for (j=1;j<=n;j++)f[i][a[i].x][j]=min(f[i][a[i].x][j],f[i+1][a[i].y][j]+a[i].z); } memset(f[mid+1],127,sizeof(f[mid])); f[mid+1][a[mid+1].y][a[mid+1].x]=f[mid+1][a[mid+1].x][a[mid+1].y]=a[mid+1].z; for (i=1;i<=n;i++) f[mid+1][i][i]=min(a[mid+1].k,f[mid+1][i][i]); for (i=mid+2;i<=r;i++){ for (j=1;j<=n;j++) for (k=1;k<=n;k++) f[i][j][k]=f[i-1][j][k]+a[i].k; for (j=1;j<=n;j++)f[i][j][a[i].y]=min(f[i][j][a[i].y],f[i-1][j][a[i].x]+a[i].z); for (j=1;j<=n;j++)f[i][j][a[i].x]=min(f[i][j][a[i].x],f[i-1][j][a[i].y]+a[i].z); } mi=x-1;mx=y+1; for (i=x;i<=y;i++) if (q[i].z<=mid && q[i].k>mid){ b[q[i].id]=1e9; for (j=1;j<=n;j++) if (f[q[i].z][q[i].x][j]<1e9 && f[q[i].k][j][q[i].y]<1e9)b[q[i].id]=min(b[q[i].id],f[q[i].z][q[i].x][j]+f[q[i].k][j][q[i].y]); }else if (q[i].k<=mid) d[++mi]=q[i]; else d[--mx]=q[i]; for (i=x;i<=mi;i++)q[i]=d[i];for (i=mx;i<=y;i++) q[i]=d[i]; dg(l,mid,x,mi);dg(mid+1,r,mx,y);}int main(){ freopen("graph.in","r",stdin);freopen("graph.out","w",stdout); scanf("%d%d%d",&n,&m,&qq);memset(b,255,sizeof(b)); for (i=1;i<=m;i++)scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].k); for (i=1;i<=qq;i++)scanf("%d%d%d%d",&q[i].x,&q[i].y,&q[i].z,&q[i].k),q[i].id=i; dg(1,m,1,qq); for (i=1;i<=qq;i++) if (b[i]!=1e9&&b[i]>=0)printf("%d\n",b[i]); else printf("-1\n");}
阅读全文
1 0
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
- jzoj5430 【NOIP2017提高A组集训10.27】图
- 【NOIP2017提高A组集训10.28】图
- 【NOIP2017提高A组集训10.28】图
- 【JZOJ 5430】【NOIP2017提高A组集训10.27】图
- JZOJ 5428. 【NOIP2017提高A组集训10.27】查询
- 【JZOJ 5428】【NOIP2017提高A组集训10.27】查询
- 【JZOJ 5429】【NOIP2017提高A组集训10.27】排列
- [JZOJ5429]【NOIP2017提高A组集训10.27】排列
- 【JZOJ5428】【NOIP2017提高A组集训10.27】查询
- 【JZOJ5429】【NOIP2017提高A组集训10.27】排列
- JZOJ5428. 【NOIP2017提高A组集训10.27】查询
- 【JZOJ5428】【NOIP2017提高A组集训10.27】查询
- 【JZOJ 5433】【NOIP2017提高A组集训10.28】图
- 【JZOJ5433】【NOIP2017提高A组集训10.28】图
- jzoj5433 【NOIP2017提高A组集训10.28】图
- jzoj【NOIP2017提高A组集训10.28】图
- Java中的选择循环结构
- java多线程实现抢红包
- JAVA代码用方法构造器来制造
- FreeMarker 快速入门
- 《木兰花令·拟古决绝词柬友》
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
- 机器学习—Bagging与随机森林算法详解
- java匿名内部类详解
- JavaScript数组
- Nginx 服务器 select 和epoll的区别
- University 继承与接口
- 深拷贝、浅拷贝
- C++ 成员函数后面加const,没有const,以及使用的区别
- 一道错题的思考