noip2013

D1:

T1:快速幂

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define LL long long 
using namespace std;
LL n,m,k,x;
inline LL quickpow(LL a,LL b){//a^b %n
    LL ans=1ll;
    while(b){
        if(b&1)ans=ans*a%n;

        a=a*a%n;
        b>>=1;
    }
    return ans;
}
int main(){
//freopen("circle.in","r",stdin);
//freopen("circle.out","w",stdout);
    
scanf("%lld%lld%lld%lld",&n,&m,&k,&x);

printf("%lld",(x%n+m*quickpow(10ll,k)%n)%n);
    
    return 0;
}

T2:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<map>
#define LL long long
using namespace std;
const int maxn=1e5+5;
const int P=99999997;
int n;
int a[maxn],b[maxn],to[maxn],ans;
map<int ,int >pa;
map<int ,int >pb;

int sum[maxn];
inline int lowbit(int x){return x&(-x);}
inline int query(int p){
    int ans=0;
    while(p){
        ans+=sum[p];
        p-=lowbit(p);
    }
    return ans;
}
inline void modify(int p){
    while(p<=n){
        sum[p]++;
        p+=lowbit(p);
    }
}
int main(){
    //freopen("match.in","r",stdin);
    //freopen("match.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        pa[a[i]]=i;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
        pb[b[i]]=i;
    }
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    /*
  这里用到了排序不等式,(a-b)^2==a^2+b^2-2ab, 找到一个排列 s.t. -2ab max 自然想到排序不等式
  正序和 <= 乱序和 <= 逆序和
  */
for(int i=1;i<=n;i++){ to[ pa[a[i]] ]=pb[b[i]]; } memset(sum,0,sizeof(sum)); ans=0; for(int i=n;i;i--){//由于是相邻的两个火柴交换,直接求逆序对 ans=(ans+query(to[i]-1))%P; modify(to[i]); } printf("%d\n",ans); return 0; }

T3:

这题挺不好想,但是从部分分出发

30` && 60` 有向图两点间最小边最大,二分答案,O(q *log( m)* m )

但是其中填边的步骤可以省略,O(q*m)--------->kruscal 第一个使得两点联通的 边就是答案

100` 我们发现 每个询问都会填边太麻烦,然后我们想,推出两个性质

1:

如果该边是答案,那么他一定在该图的最大生成树中(反证法)

2:

如果该边是答案,那么两点联通 当且仅当 该边被添加(反证法)

 

于是就得到了满分算法,最大生成树+LCA最小边

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define LL long long 
using namespace std;
const int maxn=1e4+5;
const int maxm=5e4+5;
struct Edge{
    int u;
    int v;
    int w;
    const bool operator<(const Edge &x)const{return w<x.w;}
    inline void read(){
        scanf("%d%d%d",&u,&v,&w);
    }
}e[maxm];
int n,m,q;

int father[maxn];
int find(int x){return father[x]==x ? x : father[x]=find(father[x]);}//dsu

int fst[maxn],nxt[maxm<<1],to[maxm<<1],w[maxm<<1],edge_count;
inline void add(int x,int y,int z){
    edge_count++;
    to[edge_count]=y;
    w[edge_count]=z;
    nxt[edge_count]=fst[x];
    fst[x]=edge_count;
}

inline void kruscal(){
    for(int i=1;i<=n;i++)father[i]=i;//dsu_init
    
    sort(e+1,e+m+1);
    
    for(int i=m;i;i--){//鏈€澶х敓鎴愭爲
        int fu=find(e[i].u);int fv=find(e[i].v);
        if(fu==fv)continue;
        father[fu]=fv;
        
        add(e[i].u,e[i].v,e[i].w);
        add(e[i].v,e[i].u,e[i].w);                        
    }
}
const int INF=0x3f3f3f3f;

int f[maxn][50],g[maxn][50],deep[maxn],tre[maxn],temp;
void dfs(int u,int fa){
    tre[u]=temp;

    deep[u]=deep[fa]+1;
    for(int i=1;i<30;i++){
        f[u][i]=f[ f[u][i-1] ][i-1];
        g[u][i]=min(g[ f[u][i-1] ][i-1],g[u][i-1]);
    }

    for(int i=fst[u];i;i=nxt[i]){
        int v=to[i];
        if(v==fa)continue;
        f[v][0]=u;
        g[v][0]=w[i];
        dfs(v,u);
    }
}
inline void LCA_init(){
    memset(g,0x3f,sizeof(g));
    for(int i=1;i<=n;i++)if(!deep[i]){
        temp++;        
        dfs(i,0);
    }
}

inline int LCA(int x,int y){
    int ans=INF;

    if(deep[x]<deep[y])swap(x,y);
    for(int i=29;i>=0;i--){
        if(deep[f[x][i]]>=deep[y]){
            ans=min(ans,g[x][i]);
            x=f[x][i];
        }            
    }
    if(x==y)return ans;
    for(int i=29;i>=0;i--){
        if(f[x][i]!=f[y][i]){
            ans=min(ans,min(g[x][i],g[y][i]));
            x=f[x][i];y=f[y][i];            
        }
    }
    ans=min(ans,min(g[x][0],g[y][0]));
    return ans;
}
int main(){
//freopen("truck.in","r",stdin);
//freopen("truck.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        e[i].read();
    }
    kruscal();
    LCA_init();
    
    scanf("%d",&q);    
    for(int i=1,x,y;i<=q;i++){
        scanf("%d%d",&x,&y);
        if(tre[x]!=tre[y])printf("-1\n");
        else printf("%d\n",LCA(x,y));
    }
    return 0;
}

 D2:

T1:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=1e5+5;
int n,h[maxn];
LL ans;
int main(){
   // freopen("block.in","r",stdin);
   // freopen("block.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&h[i]);
    ans=0ll;
    for(int i=1;i<=n+1;i++){
        if(h[i]<h[i-1]){
            ans+=1ll*(h[i-1]-h[i]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

T2:

O(nlogn)???

虽然不是正解但是写的很开心,O(n^2)Dp+segment tree 优化

每次x要找比x大的 将要下降的 Dp值的最大值 +1

同理

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
const int maxh=1e6+5;
/*
main thought:
segment tree,维护两个,存储一下
以num结尾的将要上升的所有Dp值
以num结尾的将要下降的所有Dp值

每次x
从第一棵树里面找所有比他 小 的值中最大的Dp值
插入第二棵数中
从第二棵树里面找所有比他 大 的值中最大的Dp值
插入第一棵树中

*/
struct Node{
    int l;
    int r;
    int len;
    Node(int L=0,int R=0,int Len=0):l(L),r(R),len(Len){}    
    inline void update(const Node&a,const Node&b){
        len=max(a.len,b.len);
    }
    inline void modify(int x){
        len=max(len,x);
    }
}L[maxh<<2][2];
//0->将要上升,1->将要下降
void build(int k,int l,int r,bool b){
    L[k][b]=Node(l,r,0);
    
    if(l==r)return;
    else{
        int mid=(l+r)>>1;
        build(k<<1,l,mid,b);
        build(k<<1|1,mid+1,r,b);    
        return;
    }
}
void modify(int k,int p,int x,bool b){
    if(L[k][b].l==L[k][b].r) return L[k][b].modify(x);
    else{
        int mid=(L[k][b].l+L[k][b].r)>>1;
        if(p<=mid)modify(k<<1,p,x,b);
        else modify(k<<1|1,p,x,b);
        return L[k][b].update(L[k<<1][b],L[k<<1|1][b]);
    }
}
int query(int k,int l,int r,bool b){//max query
    if(l<=L[k][b].l&&L[k][b].r<=r)return L[k][b].len;
    else{
        int mid=(L[k][b].l+L[k][b].r)>>1;
        int ans=0;
        if(l<=mid)ans=max(ans,query(k<<1,l,r,b));
        if(mid<r)ans=max(ans,query(k<<1|1,l,r,b));
        return ans;
    }
}
int n,h[maxn];
//0->将要上升,1->将要下降
int main(){
    //freopen("flower.in","r",stdin);
    //freopen("flower.out","w",stdout);
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&h[i]);
    build(1,0,1000000,1);
    build(1,0,1000000,0);
    for(int i=1;i<=n;i++){
        if(h[i]<1000000)modify(1,h[i],query(1,h[i]+1,1000000,1)+1,0);//将要下降的max +1 加到 将要上升 中
        if(h[i]>0)modify(1,h[i],query(1,0,h[i]-1,0)+1,1);//将要上升的max +1 加到 将要下降 中
    }
printf(
"%d\n",max( query(1,0,1000000,1) , query(1,0,1000000,0) ) ); return 0; }

注意:!!!线段树进行修改查询的时候,要注意边界!!!

神奇做法:O(n)!!!

据说是找到拐点然后+2

std:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 1000000 + 10 ;
int vis,ans,n,h[maxn];
int main()
{
    //freopen("flower.in","r",stdin);    
    //freopen("flower.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&h[i]);
    if(h[2]>=h[1]) vis=1;
    for(int i=2;i<=n;i++)
    {
        if(i==n && !vis) {ans++;break;}
        if(vis) if(h[i]>h[i+1]) {ans++;vis=0;continue;}
        if(!vis) if(h[i]<h[i+1]){ans++;vis=1;continue;}
    }
    cout<<ans+1<<endl;
    return 0;
}

 T3:

个人感觉写了双向广搜,理论上能将复杂度降低到  开一个根号

但是 忘记了 无解的情况都会跑满,所以比 单项广搜还慢一会

60`:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
/*
thought:
广搜判最短时间:
时间上:

空间上:每种状态只和空白块位置和目标快位置有关
共30^4种状态。。。

but
30^4*500=5e8

双向广搜!!!
也行,但是终止状态是4种,目标块在目标位置,空白块在4周
*/

int n,m,Q;
bool stable[50][50];
struct Node{
    int x,y;
    Node(int X=0,int Y=0):x(X),y(Y){}

    const bool operator==(const Node&a)const{
        return x==a.x&&y==a.y;
    }
    inline bool limit(){//判断是否合法
        return 0<x && x<=n && 0<y && y<=m && stable[x][y];
    }
    inline void read(){scanf("%d%d",&x,&y);}
    inline void write(){printf("%d %d\n",x,y);}
}e,s,t;
//0->正向,1->反向
struct Queue{//每种状态
    Node S,W;
    Queue(Node SS=Node(0,0),Node WW=Node(0,0)):S(SS),W(WW){}
    inline void write(){printf("~~~~~~~~~\n");S.write();W.write();printf("~~~~~~\n");}
}q[32*32*32*32][2];
int vis[32][32][32][32][2];//时间戳 判是否到达过
int step[32][32][32][32][2];//每种状态的步骤数
int front[2],rear[2];

const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
inline void bfs(int i){
//printf("------------%d\n",i);
    front[0]=front[1]=rear[0]=rear[1]=0;
    
    q[rear[0]++][0]=Queue(s,e);
    step[s.x][s.y][e.x][e.y][0]=0;
    vis[s.x][s.y][e.x][e.y][0]=i;
    //q[front[0]][0].write();
    
    
    for(int j=0;j<4;j++){
        Node a=Node(t.x+dx[j],t.y+dy[j]);
        //printf("\na::");a.write();
        if(a.limit()){
            q[rear[1]++][1]=Queue(t,a);
            step[t.x][t.y][a.x][a.y][1]=0;
            vis[t.x][t.y][a.x][a.y][1]=i;
        }
    }
    //printf("???%d %d ???",front[1],rear[1]);
    //for(int j=front[1];j<rear[1];j++)q[j][1].write();
    //printf("begin to search:::");
    
    while(front[0]<rear[0] && front[1]<rear[1]){
        if(rear[0]-front[0]<rear[1]-front[1]){
            Queue &bg=q[front[0]][0];
//printf("bg:");bg.write();

            if(vis[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][1]==i){
                printf("%d\n",step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][0]+step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][1]);
                return;
            }
            
for(int j=0;j<4;j++){
    Node a=Node(bg.W.x+dx[j],bg.W.y+dy[j]);
    if(a.limit()){
    //a.write();
        if(a==bg.S){
            q[rear[0]][0]=Queue(bg.W,bg.S);
        }
        else{
            q[rear[0]][0]=Queue(bg.S,a);
        }
        Queue &ed=q[rear[0]][0];

        if(vis[ed.S.x][ed.S.y][ed.W.x][ed.W.y][0]!=i){
            
            step[ed.S.x][ed.S.y][ed.W.x][ed.W.y][0]=step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][0]+1;
            vis[ed.S.x][ed.S.y][ed.W.x][ed.W.y][0]=i;
            rear[0]++;
        }
    }
}
            front[0]++;            
        }
        else{
            Queue &bg=q[front[1]][1];
//printf("bg:");bg.write();
            if(vis[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][0]==i){
                printf("%d\n",step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][0]+step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][1]);
                return;
            }
for(int j=0;j<4;j++){
    Node a=Node(bg.W.x+dx[j],bg.W.y+dy[j]);
    if(a.limit()){
    //a.write();
    
        if(a==bg.S){
            q[rear[1]][1]=Queue(bg.W,bg.S);
        }
        else{
            q[rear[1]][1]=Queue(bg.S,a);
        }
        Queue &ed=q[rear[1]][1];

        if(vis[ed.S.x][ed.S.y][ed.W.x][ed.W.y][1]!=i){
            
            step[ed.S.x][ed.S.y][ed.W.x][ed.W.y][1]=step[ bg.S.x ][ bg.S.y ][ bg.W.x ][ bg.W.y ][1]+1;
            vis[ed.S.x][ed.S.y][ed.W.x][ed.W.y][1]=i;
            rear[1]++;
        }
    }
}
            front[1]++;
        }
    }
    printf("-1\n");
}
int main(){
    freopen("puzzle.in","r",stdin);
    freopen("puzzle.out","w",stdout);
    scanf("%d%d%d",&n,&m,&Q);
    //printf("%d %d %d\n",n,m,Q);
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
        int _x;scanf("%d",&_x);stable[i][j]=_x;
    }
    for(int i=1;i<=Q;i++){
        e.read();//e.write();
        s.read();//s.write();
        t.read();//t.write();
        bfs(i);

        //if(i<q)memset(vis,0,sizeof(vis));
    }
    return 0;
}

70`:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxm = 30 + 5;
bool vis[maxm][maxm][maxm][maxm];
int map[maxm][maxm],n,m,q;
int exe,eye,sxs,sys,txt,tyt;
int dx[5]={0,0,0,1,-1},dy[5]={0,1,-1,0,0};
struct Node{int ex,ey,sx,sy,d;};
int bfs()
{
    queue<Node> pq;
    pq.push((Node){exe,eye,sxs,sys,0});
    vis[exe][eye][sxs][sys]=1;
    while(!pq.empty())
    {
        int ex=pq.front().ex,ey=pq.front().ey,sx=pq.front().sx,sy=pq.front().sy,d=pq.front().d;
        pq.pop();
        for(int i=1;i<=4;i++)
        {
            int nx=ex+dx[i],ny=ey+dy[i];
            if(nx<1 || nx>n || ny<1 || ny>m || !map[nx][ny]) continue; 
            if(nx==sx && ny==sy){
                if(vis[nx][ny][ex][ey]) continue;
                if(ex==txt && ey==tyt) return d+1;
                else{
                    pq.push((Node){nx,ny,ex,ey,d+1});vis[nx][ny][ex][ey]=1;
                }
            }
            else
            {
                if(vis[nx][ny][sx][sy]) continue;
                pq.push((Node){nx,ny,sx,sy,d+1});vis[nx][ny][sx][sy]=1;
            }
        }
    }
    return -1;
}
int main()
{
    freopen("puzzle.in","r",stdin);
    freopen("puzzle.out","w",stdout);
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&map[i][j]);
    for(int i=1;i<=q;i++)
    {
        memset(vis,0,sizeof(vis));
        scanf("%d%d%d%d%d%d",&exe,&eye,&sxs,&sys,&txt,&tyt);
        cout<<(sxs==txt&&sys==tyt?0:bfs())<<endl;
    }
    return 0;
}

std:懂了,就是写的非常曲折,总共改了10多次。。。

(ps:好题,值得一做)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstdlib>
  6 #include<algorithm>
  7 using namespace std;
  8 /*
  9 thought:
 10 暴力预处理+ 对没种状态建图+spfa
 11 */
 12 const int INF=0x3f3f3f3f;
 13 
 14 int n,m,Q;
 15 bool stable[50][50];
 16 struct Node{
 17     int x,y;
 18     Node(int X=0,int Y=0):x(X),y(Y){}
 19 
 20     const bool operator==(const Node&a)const{
 21         return x==a.x&&y==a.y;
 22     }
 23     inline bool limit(){//判断是否合法
 24         return 0<x && x<=n && 0<y && y<=m && stable[x][y];
 25     }
 26     inline void read(){scanf("%d%d",&x,&y);}
 27     inline void write(){printf("%d %d\n",x,y);}
 28 }e,s,t;
 29 const int dx[4]={0,1,0,-1};
 30 const int dy[4]={1,0,-1,0};//下,右,上,左 
 31 
 32 int fst[40000],nxt[1000000],to[1000000],w[1000000],edge_count=0;
 33 inline void add(int x,int y,int z){
 34     edge_count++;
 35     to[edge_count]=y;
 36     w[edge_count]=z;
 37     nxt[edge_count]=fst[x];
 38     fst[x]=edge_count;
 39 }
 40 inline int get_hash(int x,int y,int k){
 41     return y*1000+x*10+k;
 42 }//状态转数字
 43 inline Node get_Node(int a){
 44     int xx,yy;
 45     a/=10;
 46     xx=a%100;
 47     a/=100;
 48     yy=a;
 49     return Node(xx,yy);
 50 }
 51 bool vis[32][32];
 52 int step[32][32];
 53 Node q[32*32];
 54 inline int bfs(Node S,Node T){
 55     if(!S.limit() || !T.limit())return INF;
 56     
 57     memset(vis,0,sizeof(vis));
 58     
 59     int front,rear;
 60     front=rear=0;
 61     
 62     q[rear++]=S;
 63     vis[S.x][S.y]=1;
 64     step[S.x][S.y]=0;
 65     while(front<rear){
 66         Node &bg=q[front];
 67         if(bg==T)return step[bg.x][bg.y];
 68         
 69         for(int j=0;j<4;j++){
 70             Node a=Node(bg.x+dx[j],bg.y+dy[j]);
 71             if(a.limit() && !vis[a.x][a.y]){
 72                 
 73                 /*if(S==Node(3,1)&&T==Node(1,1)){
 74                 printf("%d",stable[a.x][a.y]);
 75                 //a.write();
 76             }*/
 77                 
 78                 step[a.x][a.y]=step[bg.x][bg.y]+1;
 79                 vis[a.x][a.y]=1;
 80                 q[rear++]=a;
 81             }
 82         }
 83         front++;
 84     }
 85     return INF;
 86 }
 87 
 88 inline void Spfa_init(){
 89     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
 90         if(stable[i][j]){
 91             stable[i][j]=0;
 92             
 93             for(int k=0;k<4;k++)
 94             {
 95                 Node a=Node(i+dx[k],j+dy[k]);
 96                 if(a.limit())add(get_hash(i,j,k),get_hash(a.x,a.y,(k+2)%4),1);
 97                 
 98                 for(int l=k+1;l<4;l++){
 99                     Node S=Node(i+dx[k],j+dy[k]);
100                     Node T=Node(i+dx[l],j+dy[l]);
101                     if(!S.limit() || !T.limit())continue;
102                    
103                     int t=bfs(S,T);
104                     //if(S==Node(3,1)&&T==Node(1,1))cout<<i<<j<<endl;
105                     if(t!=INF)
106     //建图:(x,y,z)表示目标格子在(x,y)空白格子在z方向,向4个方向建边 
107                     {
108                         add(get_hash(i,j,k),get_hash(T.x,T.y,(l+2)%4),t+1);
109                         add(get_hash(i,j,l),get_hash(S.x,S.y,(k+2)%4),t+1);
110                     }
111                     
112                     
113                 }
114             }
115             
116             stable[i][j]=1;
117         }
118     }
119 }
120 
121 inline int bfs_sec(Node &E,Node S){
122     memset(vis,0,sizeof(vis));
123     
124     int front,rear;
125     front=rear=0;
126     
127     q[rear++]=E;
128     vis[E.x][E.y]=1;
129     step[E.x][E.y]=0;
130     
131     while(front<rear){
132         Node &bg=q[front];
133         
134         for(int j=0;j<4;j++){
135             Node a=Node(bg.x+dx[j],bg.y+dy[j]);
136             
137             if(a==S){
138                 E=bg;
139                 //E.write();
140                 
141                 return step[bg.x][bg.y];
142             }
143             
144             if(a.limit() && !vis[a.x][a.y]){
145                 step[a.x][a.y]=step[bg.x][bg.y]+1;
146                 vis[a.x][a.y]=1;
147                 q[rear++]=a;
148             }
149         }
150         front++;
151     }
152     return INF;
153 }
154 int que[400000],dis[400000];
155 bool inqueue[40000];
156 inline int spfa(int ss,Node T){
157     /*知道自己错在哪里了: 
158     我的想法是 一开始让空白块跑到目标块旁边
159     但是这种方法会有漏洞,就是这次的路径可能以后的最优解会路过
160     
161     也就是起点不在图里,需要从起点的上下左右跑一边再计算最短路 
162     */
163     memset(dis,0x3f,sizeof(dis));
164     int ans=INF;
165     
166     int front,rear;
167     front=rear=0;
168     
169     que[rear++]=ss;
170     dis[ss]=0;
171     inqueue[ss]=1;
172     
173     while(front<rear){
174         int &bg=que[front];
175         //printf("%d:\n",bg);        
176         if(get_Node(que[front])==T)ans=min(ans,dis[bg]);
177         
178         for(int i=fst[bg];i;i=nxt[i]){
179             int v=to[i];
180             //printf(" v%d ",v);
181             int tt=dis[bg]+w[i];
182             //printf("dis%d\n",tt);
183             
184             if(tt<dis[v]){
185                 dis[v]=tt;
186                 if(!inqueue[v]){
187                     que[rear++]=v;
188                     inqueue[v]=1;
189                 }
190             }
191             
192         }
193         
194         inqueue[bg]=0;
195         front++;
196     }
197     return ans;
198 }
199 inline void solve(){
200     if(s==t){
201         printf("0\n");
202         return;
203     }
204     stable[s.x][s.y]=0;
205     
206     int ans=INF;
207     for(int i=0;i<4;i++){
208         int a=spfa(get_hash(s.x,s.y,i),t);
209         if(a==INF)continue;
210         
211         int b=bfs(Node(s.x+dx[i],s.y+dy[i]),e);
212         if(b==INF)continue;
213         
214         ans=min(ans,a+b);
215     }
216     stable[s.x][s.y]=1;
217     
218     if(ans==INF)printf("-1\n");
219     else printf("%d\n",ans);
220 }
221 int main(){
222     //freopen("puzzle.in","r",stdin);
223     //freopen("puzzle.out","w",stdout);
224     scanf("%d%d%d",&n,&m,&Q);
225     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
226         int _x;scanf("%d",&_x);stable[i][j]=_x;
227     }
228     Spfa_init();
229     
230     for(int i=1;i<=Q;i++){
231         e.read();//e.write();
232         s.read();//s.write();
233         t.read();//t.write();
234         solve(); 
235         //if(i<q)memset(vis,0,sizeof(vis));
236     }
237     return 0;
238 }
239 /*
240 3 3 1
241 1 1 1
242 1 0 1
243 1 1 1
244 3 1 1 1 1 2
245 */
bug * 12 and debug for 4 hours

 

posted @ 2019-08-27 19:33  Tj1  阅读(149)  评论(0编辑  收藏  举报