【JZOJ5430】图
来源:互联网 发布:淘宝球鞋店 编辑:程序博客网 时间:2024/06/08 15:29
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开始
Solution
考虑分治边,记录
把询问挂在左端点上,计算跨越
Code
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#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 rep(i,x) for(int i=ls[x];i;i=nx[i])#define N 20020#define M 200010#define inf 1010580540using namespace std;struct node{ int x,y,p,q; int ans;}e[N],Q[M];int to[M],nx[M],ls[N],num=0;int f[N][31][31];void link(int x,int y){ to[++num]=y,nx[num]=ls[x],ls[x]=num;}void qmin(int &x,int y){ if(x>y) x=y;}int n;void fz(int l,int r){ if(l==r) return; int mid=(l+r)/2; fo(i,l,r) fo(x,1,n) fo(y,1,n) f[i][x][y]=inf; fo(x,1,n) { f[mid][x][x]=e[mid].q; if(e[mid].x==x) qmin(f[mid][x][e[mid].y],e[mid].p); if(e[mid].y==x) qmin(f[mid][x][e[mid].x],e[mid].p); fd(i,mid-1,l) { fo(y,1,n) f[i][x][y]=f[i+1][x][y]+e[i].q; qmin(f[i][x][e[i].y],f[i+1][x][e[i].x]+e[i].p); qmin(f[i][x][e[i].x],f[i+1][x][e[i].y]+e[i].p); } f[mid+1][x][x]=e[mid+1].q; if(e[mid+1].x==x) qmin(f[mid+1][x][e[mid+1].y],e[mid+1].p); if(e[mid+1].y==x) qmin(f[mid+1][x][e[mid+1].x],e[mid+1].p); fo(i,mid+2,r) { fo(y,1,n) f[i][x][y]=f[i-1][x][y]+e[i].q; qmin(f[i][x][e[i].y],f[i-1][x][e[i].x]+e[i].p); qmin(f[i][x][e[i].x],f[i-1][x][e[i].y]+e[i].p); } } fd(i,mid,l) rep(j,i){ int v=to[j]; if(Q[v].q>mid && Q[v].q<=r){ int x=Q[v].x,y=Q[v].y; fo(z,1,n) qmin(Q[v].ans,f[i][z][x]+f[Q[v].q][z][y]); } } fz(l,mid),fz(mid+1,r);}int main(){ freopen("graph.in","r",stdin); freopen("graph.out","w",stdout); int m,q; scanf("%d %d %d",&n,&m,&q); fo(i,1,m) scanf("%d %d %d %d",&e[i].x,&e[i].y,&e[i].p,&e[i].q); fo(i,1,q) { scanf("%d %d %d %d",&Q[i].x,&Q[i].y,&Q[i].p,&Q[i].q); Q[i].ans=inf; if(Q[i].p!=Q[i].q) link(Q[i].p,i); else{ int o=Q[i].p; if(Q[i].x==Q[i].y) Q[i].ans=e[o].q; if(Q[i].x==e[o].x && Q[i].y==e[o].y || Q[i].x==e[o].y && Q[i].y==e[o].x) qmin(Q[i].ans,e[o].p); } } fz(1,m); fo(i,1,q) printf("%d\n",Q[i].ans>=inf?-1:Q[i].ans);}
阅读全文
1 0
- 【JZOJ5430】图
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
- jzoj5430 【NOIP2017提高A组集训10.27】图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- 图
- Java程序性能优化 读书笔记(九)优化组件:池
- 怎样完全卸载tensorflow?
- 数组、链表和哈希表
- jsp+servlet(4)
- 8254定时/计数器实验
- 【JZOJ5430】图
- 函数的调用过程(栈帧)
- PHP调用微信接口现金红包功能
- 日志服务 & 日志同步 & 时间同步
- 『0005』- 以太坊智能合约生命周期(Ethereum smart contracts lifecycle)
- 我的前端复习之路
- 给你讲一个只有程序员才能听得懂得笑话
- linux(ubuntu)下创建eclipse快捷方式
- 【BZOJ3236】【AHOI2013】作业 线段树 分治 树状数组