图
Description
有一个
n
个点的无向图,给出
给出
q
组询问形如(
接下来解释询问以及边的意义。
询问表示,一开始你在点
对于一条边(
x
,
1
、如果你当前在
2
、如果你不走这条边或者不可以走这条边(即你当前不在
询问如果要从
u
点开始,按顺序处理完编号从
边和点的编号从
1
开始。
Data Constraint
Solution
离线,考虑分治。
假设当前在处理分治边区间[
L
,
显然从
总时间复杂度
O
(
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,j,l) for(int i=j;i<=l;i++)
#define fd(i,j,l) for(int i=j;i>=l;i--)
using namespace std;
typedef long long ll;
const ll N=31,M=22e3,K=10*M,maxn=1e14;
struct note{
int x,y,l,r;
}t[M],qu[K];
int ne[K],la[M],lb[K];
ll dis[M][N][N],ans[K];
int n,m,j,k,l,i,o,p,q;
int read()
{
int o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+ch-48;
return o;
}
ll min(ll a,ll b)
{if(a<b)return a;else return b;}
void divide(int l,int r,int op)
{
if(l==r){
fo(i,1,n)fo(j,1,n)dis[l][i][j]=maxn;
int x=t[l].x,y=t[l].y;
fo(j,1,n)dis[l][j][j]=t[l].r;
dis[l][x][y]=dis[l][y][x]=t[l].l;
for(int y=la[l];y;y=ne[y]){
int u=lb[y];
if(qu[u].r==l)ans[u]=dis[l][qu[u].x][qu[u].y];
}
return;
}
int mid=(l+r)/2;
divide(l,mid,0); divide(mid+1,r,1);
fo(i,1,n)fo(j,1,n)dis[mid][i][j]=maxn;
int x=t[mid].x,y=t[mid].y;
dis[mid][x][y]=dis[mid][y][x]=t[mid].l;
fo(j,1,n)dis[mid][j][j]=min(t[mid].r,dis[mid][j][j]);
fd(i,mid-1,l){
int x=t[i].x,y=t[i].y;
fo(j1,1,n)fo(j2,1,n)dis[i][j1][j2]=dis[i+1][j1][j2]+t[i].r;
fo(j,1,n)dis[i][j][x]=min(dis[i+1][j][y]+t[i].l,dis[i][j][x]);
fo(j,1,n)dis[i][j][y]=min(dis[i+1][j][x]+t[i].l,dis[i][j][y]);
}
fo(i,1,n)fo(j,1,n)dis[mid+1][i][j]=maxn;
x=t[mid+1].x,y=t[mid+1].y;
dis[mid+1][x][y]=dis[mid+1][y][x]=t[mid+1].l;
fo(j,1,n)dis[mid+1][j][j]=min(t[mid+1].r,dis[mid+1][j][j]);
fo(i,mid+2,r){
int x=t[i].x,y=t[i].y;
fo(j1,1,n)fo(j2,1,n)dis[i][j1][j2]=dis[i-1][j1][j2]+t[i].r;
fo(j,1,n)dis[i][j][x]=min(dis[i-1][j][y]+t[i].l,dis[i][j][x]);
fo(j,1,n)dis[i][j][y]=min(dis[i-1][j][x]+t[i].l,dis[i][j][y]);
}
fo(i,l,mid){
for(int y=la[i];y;y=ne[y]){
int u=lb[y];
if(qu[u].r>mid&&qu[u].r<=r){
int xx=qu[u].x,yy=qu[u].y;
int le=qu[u].l,ri=qu[u].r;
ans[u]=maxn;
fo(j,1,n)ans[u]=min(ans[u],dis[le][j][xx]+dis[ri][j][yy]);
}
}
}
}
int main()
{
cin>>n>>m>>q;
fo(i,1,m)t[i].x=read(),t[i].y=read(),t[i].l=read(),t[i].r=read();
fo(i,1,q)qu[i].x=read(),qu[i].y=read(),
qu[i].l=read(),qu[i].r=read();
fo(i,1,q)ne[++o]=la[qu[i].l],la[qu[i].l]=o,lb[o]=i;
divide(1,m,1);
fo(i,1,q)if(ans[i]>=maxn)puts("-1");else printf("%lld\n",ans[i]);
}