请求增加时间

P3350 [ZJOI2016] 旅行者

__Hacheylight__ @ 2018-07-31 21:03:41

BZOJ20 sec luogu只有2 sec

我BZOJ AC了,洛谷70,怀疑被卡常,请求放宽时限。。。

#include <bits/stdc++.h>
using namespace std ;

const int N = 20010 ;
const int M = 100010 ;
const int inf = INT_MAX ;
typedef pair<int,int > pii ;

struct edge{
    int to,w,nxt ;
}e[N<<2];
struct node{
    int s1,e1,s2,e2,id ;
}q[M],p[M];//p为中转的 

int w,n,m,cnt,tot ;
int X[N],Y[N],dis[N],ans[M],head[N] ;
bool vis[N] ;

inline int id(int x,int y){return (x-1)*m+y;}
inline void add(int u,int v,int w){
    e[++cnt].w=w; 
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt ;
}
inline void dijkstra(int st,int s1,int e1,int s2,int e2){
//  cout<<st<<" "<<s1<<" "<<e1<<" "<<s2<<" "<<e2<<endl ;
    priority_queue<pii,vector<pii>,greater<pii> > q;
    for (int i=s1;i<=s2;i++)
    for (int j=e1;j<=e2;j++){
        int x=id(i,j);
        dis[x]=inf;
        vis[x]=false;
    }
    dis[st]=0;
    q.push(make_pair(0,st));
    while (!q.empty()){
        int x=q.top().second; q.pop();
        if (vis[x]) continue;
        vis[x]=true;
        for (int i=head[x];i;i=e[i].nxt)
        if (dis[e[i].to]>dis[x]+e[i].w)
        if (X[e[i].to]>=s1&&X[e[i].to]<=s2&&Y[e[i].to]>=e1&&Y[e[i].to]<=e2) {
            dis[e[i].to]=dis[x]+e[i].w;
            q.push(make_pair(dis[e[i].to],e[i].to));
        }
    }
} 

inline void solve(int s1,int e1,int s2,int e2,int L,int R){
//  cout<<s1<<" "<<e1<<" "<<s2<<" "<<e2<<" "<<L<<" "<<R<<endl ; 
    if (L>R) return ;
    if (s2-s1>e2-e1){
        int mid=s1+s2>>1 ;
        for (int i=e1;i<=e2;i++){
            dijkstra(id(mid,i),s1,e1,s2,e2) ;
            for (int j=L;j<=R;j++){
                ans[q[j].id]=min(ans[q[j].id],dis[id(q[j].s1,q[j].e1)]+dis[id(q[j].s2,q[j].e2)]) ;
            } 
        }
        int l=L-1,r=R+1 ;
        for (int i=L;i<=R;i++){
            if (q[i].s1<mid && q[i].s2<mid) p[++l]=q[i] ;
            else if (q[i].s1>mid && q[i].s2>mid) p[--r]=q[i] ;
        }
        for (int i=L;i<=l;i++) q[i]=p[i] ;
        for (int i=R;i>=r;i--) q[i]=p[i] ;
        solve(s1,e1,mid-1,e2,L,l); solve(mid+1,e1,s2,e2,r,R);
    }
    else {
        int mid=e1+e2>>1 ;
        for (int i=s1;i<=s2;i++){
            dijkstra(id(i,mid),s1,e1,s2,e2) ;
            for (int j=L;j<=R;j++){
                ans[q[j].id]=min(ans[q[j].id],dis[id(q[j].s1,q[j].e1)]+dis[id(q[j].s2,q[j].e2)]) ;
            } 
        }
        int l=L-1,r=R+1 ;
        for (int i=L;i<=R;i++){
            if (q[i].e1<mid && q[i].e2<mid) p[++l]=q[i] ;
            else if (q[i].e1>mid && q[i].e2>mid) p[--r]=q[i] ;
        }
        for (int i=L;i<=l;i++) q[i]=p[i] ;
        for (int i=R;i>=r;i--) q[i]=p[i] ;
        solve(s1,e1,s2,mid-1,L,l); solve(s1,mid+1,s2,e2,r,R);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    for (int j=1;j<=m;j++){
        X[id(i,j)]=i ;
        Y[id(i,j)]=j ;
    }
    for (int i=1;i<=n;i++){
        for (int j=1;j<m;j++){
            scanf("%d",&w) ;
            int a=id(i,j),b=id(i,j+1) ;
            add(a,b,w) ;
            add(b,a,w) ; 
        }
    }
    for (int i=1;i<n;i++){
        for (int j=1;j<=m;j++){
            scanf("%d",&w) ;
            int a=id(i,j),b=id(i+1,j) ;
            add(a,b,w) ;
            add(b,a,w) ; 
        }
    } //建图完毕 
    int Q ; 
    scanf("%d",&Q) ;
    for (int i=1;i<=Q;i++){
        int s1,s2,e1,e2 ;
        scanf("%d%d%d%d",&s1,&e1,&s2,&e2) ;
        if (s1==s2 && e1==e2) ans[i]=0;
        else {
            q[++tot]=(node){s1,e1,s2,e2,i} ;
            ans[i]=inf ;
        }
    }
    solve(1,1,n,m,1,tot);
    for (int i=1;i<=Q;i++) printf("%d\n",ans[i]) ;
}

|