1 条题解

  • 1

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define N 1110
    #define inf 0x7f7f7f7f
    #define P(x,y) (x*(m+1)+y)
    //#define V(x,y,k) (rank[P(x,y)][k])
    #define V(A,K) (Rank[A][K])
    #define NP(A,K) (A+D[K])
    int D[4]={-1,1};
    //static const int D[]={-1,1,-m-1,m+1};//

    int n,m,q;

    int Rank[N][4];//V(i,j,k)表示(i,j)点k方向有空白格子
    int R=0;

    int map[N];

    struct Edge{
    int v,val;
    Edge *link;
    };

    Edge *graph[N*4];
    Edge node[N*50];
    int top=0;

    inline void add(int u,int v,int val) {
    Edge *p=&node[top++];
    p->v=v;
    p->val=val;
    p->link=graph[u];
    graph[u]=p;
    }

    typedef pair<int,int> pii;
    bool vis[N];// used for BFS
    queue<pii> qq;

    int BFS(const int u,const int v,const int k) {//u to v do not through k
    if( u==k || v==k ) return inf;
    if( u==v ) return 0;

    while(!qq.empty()) qq.pop();
    memset(vis,false,sizeof(vis));

    int l,y;
    qq.push(make_pair(u,0));
    vis[u]=true;
    while(!qq.empty()) {
    pii t=qq.front();qq.pop();
    for(l=0;l<4;l++) {
    y=NP(t.first,l);
    if( vis[y] || y==k || !map[y] ) continue;
    if( y==v )
    return t.second+1;
    qq.push(make_pair(y,t.second+1));
    vis[y]=true;
    }
    }
    return inf;
    }

    bool inq[N*4];// used for spfa
    int dist[N*4];
    queue<int> Q;

    void spfa() {
    while(!Q.empty()) {
    int t=Q.front();Q.pop();
    inq[t]=false;
    for(Edge *p=graph[t];p;p=p->link) {
    int v=p->v;
    if(dist[v]>dist[t]+p->val) {
    dist[v]=dist[t]+p->val;
    if(!inq[v]) {
    inq[v]=true;
    Q.push(v);
    }
    }
    }
    }
    }

    int main(){
    //freopen("puzzle.in","r",stdin);
    //freopen("out.txt","w",stdout);

    int i,j,k,l;
    scanf("%d%d%d",&n,&m,&q);

    //因为是从1开始存,所以每排是(m+1)
    //static const int D[]={-1,1,-m-1,m+1};//
    D[2]=-m-1; D[3]=m+1;
    // left right up down

    for(i=1;i<=n;i++) for(j=1;j<=m;j++) {
    scanf("%d",&map[P(i,j)]);
    if(map[P(i,j)]) for(k=0;k<4;k++) //give the node number
    Rank[P(i,j)][k]=R++;
    }

    int u,v,t;
    for(i=1;i<=n;i++) for(j=1;j<=m;j++)
    if( map[ u=P(i,j) ] )
    for(k=0;k<4;k++) if( map[ v=NP(u,k)] ){
    //link a way val 1 V(u,k) to V(v,k^1)
    // k^1 means 1 aginst 0 (left right) 2 aginst 3 (up down)
    add(V(u,k),V(v,k^1),1);

    for(l=0;l<4;l++) if( l!=k&& map[ t=NP(u,l)] ) {//turn
    // find a way do not through U V to T D=dist
    // if D !=inf then link a way V(U,k) to V(U,l)
    int D=BFS(v,t,u);
    if(D!=inf)
    add(V(u,k),V(u,l),D);
    }
    }

    int Ex,Ey,Sx,Sy,Tx,Ty;

    while(q--) {
    scanf("%d%d%d%d%d%d",&Ex,&Ey,&Sx,&Sy,&Tx,&Ty);

    if( (Ex==Sx&&Ey==Sy) || !map[P(Ex,Ey)] || !map[P(Sx,Sy)] || !map[P(Tx,Ty)] ) {
    printf("-1\n");
    continue;

    }
    if( Tx==Sx&&Ty==Sy ) {
    printf("0\n");
    continue;
    }

    for(i=0;i<=R;i++) dist[i]=inf;

    u=P(Sx,Sy);
    for(k=0;k<4;k++) if( map[ v=NP(u,k)] ){
    // find a way do not through u | E to v D=dist
    // if D != inf push into SPFA_queue and put dist[v]=D
    int D=BFS(P(Ex,Ey),v,u);
    if(D==inf) continue;

    Q.push(V(u,k));
    dist[V(u,k)]=D;
    inq[V(u,k)]=true;
    }
    spfa();
    int ans=inf;
    u=P(Tx,Ty);
    for(k=0;k<4;k++)
    if(ans>dist[V(u,k)])
    ans=dist[V(u,k)];
    printf("%d\n",ans==inf?-1:ans);
    }

    //fclose(stdin);
    //fclose(stdout);
    return 0;
    }

  • 1

信息

ID
1404
难度
9
分类
(无)
标签
递交数
2
已通过
2
通过率
100%
上传者