[最短路] HDU 5910 Advanced Traffic System

理解了有一会儿,但是题解确实说清楚了

这里写图片描述

关键是只需要更新一遍

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<queue>
#define pb push_back
using namespace std;
typedef pair<int,int> abcd;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
  char c=nc(),b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

const int N=90005;

vector<int> q[N<<2],f[N<<2]; int size[N<<2];
inline int Fatq(int x,int u){
  return f[x][u]==u?u:f[x][u]=Fatq(x,f[x][u]);
}
int pos[N];
inline void Build(int x,int l,int r){
  q[x].clear(); f[x].clear();
  q[x].pb(0); f[x].pb(0); size[x]=0;
  if (l==r) return void(pos[l]=x);
  int mid=(l+r)>>1; Build(x<<1,l,mid); Build(x<<1|1,mid+1,r);
}
inline void Add(int x,int l,int r,int ql,int qr,int t){
  if (ql<=l && r<=qr){
    q[x].pb(t); f[x].pb(++size[x]); return;
  }
  int mid=(l+r)>>1;
  if (ql<=mid) Add(x<<1,l,mid,ql,qr,t);
  if (qr>mid) Add(x<<1|1,mid+1,r,ql,qr,t);
}

priority_queue<abcd,vector<abcd>,greater<abcd> > Q;
int dis[N];
int fat[305][305];

inline int Fat(int x,int y){
  return fat[x][y]==y?y:fat[x][y]=Fat(x,fat[x][y]);
}

int vst[N];

int n,m,e,sx,sy;
int L[N],R[N],A[N],B[N],dx[N],C[N],D[N],dy[N],w[N];
int idx[305][305];

inline void Modify(int x,int d){
  x=pos[x];
  while (x){
    for (int i=Fatq(x,size[x]);i;i=Fatq(x,i)){
      int t=q[x][i];
      if (!vst[t])
    Q.push(abcd(d+w[t],t)),vst[t]=1;
      f[x][i]=i-1;
    }
    x>>=1;
  }
}

inline void Dij(){
  while (!Q.empty()) Q.pop();
  dis[idx[sx][sy]]=0; Modify(idx[sx][sy],0); fat[sx][sy]=sy+1;
  while (!Q.empty()){
    abcd t=Q.top(); Q.pop();
    int u=t.second,c=C[u],d=D[u],dy=::dy[u];
    for (int i=A[u];i<=B[u];i+=dx[u]){
      for(int j=c;;){
    j=Fat(i,j),j=((j-c)/dy+((j-c)%dy>0))*dy+c;
    if (j>d) break;
    if (fat[i][j]!=j) continue;
    dis[idx[i][j]]=t.first;
    Modify(idx[i][j],t.first);
    fat[i][j]=j+1;
      }
    }
  }
}

int main(){
  int T;
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(T);
  while (T--){
    read(n); read(m); read(e); read(sx); read(sy);
    for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) read(idx[i][j]),fat[i][j]=j; fat[i][m+1]=m+1; }
    Build(1,1,n*m);
    for (int i=1;i<=e;i++){
      read(L[i]),read(R[i]),read(A[i]),read(B[i]),read(dx[i]),read(C[i]),read(D[i]),read(dy[i]),read(w[i]);
      Add(1,1,n*m,L[i],R[i],i); vst[i]=0;
    }
    for (int i=1;i<=n*m;i++) dis[i]=-1;
    Dij();
    for (int i=1;i<=n*m;i++) printf("%d%c",dis[i],i!=n*m?' ':'\n');
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值