zoukankan      html  css  js  c++  java
  • [bzoj2574] [Poi1999]Store-Keeper

      坑啊。。

      膜了半天byvoid大爷的题解。https://www.byvoid.com/blog/poi-1999-mag/?replytocom=1335/

      一开始从人的位置bfs一波,看看能走到初始包裹哪些方向上。要注意不能穿过初始包裹...byvoid的标程在处理穿过包裹什么的地方有问题...但数据略弱。

      之后如题解所述。

      发现自己不会求点双连通分量QAQ。。那部分就抄标程了...

      大概就是记录一下当前走过的边,遇到割点就一直出栈...和求强连通分量差不多,就是一个点可能在多个点双里面..这个比较烦

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=10023;
      7 const int xx[4]={-1,1,0,0},yy[4]={0,0,-1,1};
      8 struct zs{int too,pre;}e[maxn<<2];int tot,last[maxn];
      9 int too[2333333],pre[2333333],la[maxn],tt,st1[maxn],top,cnt,st2[maxn],uuu[103][103][4][4];bool uu[maxn];
     10 struct poi{int x,y;}S,T,M;
     11 struct zs1{int x,y,dir;}dl[maxn<<2];
     12 int dfn[maxn],low[maxn],tim;
     13 bool gd[maxn],u[maxn];
     14 int id[103][103],dis[103][103][4],q[maxn];
     15 char mp[103][103];
     16 int i,j,k,n,m,man,st,ed;
     17  
     18 inline void ins(int a,int b){
     19     int i=la[a];
     20     while(i&&too[i]!=b)i=pre[i];
     21     if(i)return;
     22     too[++tt]=b,pre[tt]=la[a],la[a]=tt;
     23 }
     24 inline bool same(int a,int b){
     25     int i;bool flag;
     26     for(i=la[a];i;i=pre[i])uu[too[i]]=1;
     27     for(i=la[b];i&&!uu[too[i]];i=pre[i]);
     28     flag=i!=0;
     29     for(i=la[a];i;i=pre[i])uu[too[i]]=0;
     30     return flag;
     31 }
     32 inline bool canget(int x,int y,int dir1,int dir2){
     33     if(!gd[id[x][y]])return 1;
     34     if(uuu[x][y][dir1][dir2]<0)
     35         return (uuu[x][y][dir1][dir2]=same( id[x+xx[dir1]][y+yy[dir1]] , id[x+xx[dir2]][y+yy[dir2]] ));
     36     else return uuu[x][y][dir1][dir2];
     37 }
     38 void tarjan(int x,int fa){
     39     dfn[x]=low[x]=++tim;int too,u,v;
     40     for(int i=last[x];i;i=e[i].pre)if(dfn[e[i].too]<dfn[x]){
     41         too=e[i].too;
     42         if(!dfn[too]){
     43             st1[++top]=x,st2[top]=too;
     44             tarjan(too,x),low[x]=min(low[x],low[too]);
     45             if(low[too]>=dfn[x]){
     46                 gd[x]=1;
     47                 cnt++;
     48                 do{
     49                     u=st1[top],v=st2[top],
     50                     ins(u,cnt),ins(v,cnt),top--;
     51                 }while((u!=x||v!=too)&&(u!=too||v!=x));
     52             }
     53         }
     54         else low[x]=min(low[x],dfn[e[i].too]);
     55     }
     56 }
     57  
     58 inline void insert(int a,int b){
     59     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
     60     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
     61 }
     62  
     63 inline bool check(int x,int y){return x>0&&y>0&&x<=n&&y<=m&&mp[x][y]!='S';}
     64  
     65 inline void bfs(int s){
     66     int l=0,r=1,i,now;q[1]=s,u[s]=1;
     67     while(l<r)
     68         for(i=last[now=q[++l]];i;i=e[i].pre)if(!u[e[i].too]&&e[i].too!=st)
     69             u[e[i].too]=1,q[++r]=e[i].too;
     70 }
     71 inline int run(){
     72     int l=0,r=0,i,nx,ny,ndir,ndis,x,y;
     73     for(i=0;i<4;i++){
     74         x=S.x+xx[i],y=S.y+yy[i];
     75         if(check(x,y)&&u[id[x][y]])dl[++r]=(zs1){S.x,S.y,i},dis[S.x][S.y][i]=1;//,printf("st:%d,%d
    ",x,y);
     76     }
     77     while(l<r){
     78         l++,nx=dl[l].x,ny=dl[l].y,ndir=dl[l].dir,ndis=dis[nx][ny][ndir];
     79         x=nx+xx[ndir^1],y=ny+yy[ndir^1];//printf("case:%d,%d  dis:%d  dir:%d
    ",nx,ny,ndis,ndir);
     80         if(!check(x,y))continue;
     81         if(x==T.x&&y==T.y)return ndis;
     82         for(i=0;i<4;i++)
     83             if(check(x+xx[i],y+yy[i])&&!dis[x][y][i]&&canget( x,y,ndir,i ))
     84                 dis[x][y][i]=ndis+1,dl[++r]=(zs1){x,y,i};
     85     }
     86     return -233;
     87 }
     88 int main(){
     89     memset(uuu,200,sizeof(uuu));
     90     scanf("%d%d",&n,&m);int tmp=0;tot=1;
     91     for(i=1;i<=n;i++){
     92         scanf("%s",mp[i]+1);
     93         for(j=1;j<=m;j++)if(mp[i][j]!='S'){
     94             id[i][j]=++tmp;
     95             for(k=0;k<4;k+=2){
     96                 int x=i+xx[k],y=j+yy[k];
     97                 if(check(x,y))
     98                     insert(id[i][j],id[x][y]);//,printf("(%d,%d)-->(%d,%d)
    ",x,y,i,j);
     99             }
    100             if(mp[i][j]=='M')man=tmp,M=(poi){i,j};
    101             if(mp[i][j]=='P')st=tmp,S=(poi){i,j};
    102             if(mp[i][j]=='K')ed=tmp,T=(poi){i,j};
    103         }
    104     }//return 233;
    105     for(i=1;i<=tmp;i++)if(!dfn[i])tarjan(i,0);
    106 //  for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(id[i][j]){
    107 //      if(mp[i][j]!='S')printf("(%d,%d)  %d   fa:%d
    ",i,j,id[i][j],getfa(id[i][j]));
    108 //      if(gd[id[i][j]])printf("        gd:  (%d,%d)
    ",i,j);
    109 //  }
    110     bfs(man);
    111     int ans=run();
    112     if(ans<0)puts("NO");else printf("%d
    ",ans);
    113 }
    View Code
  • 相关阅读:
    docker 数据卷 ---- 进阶篇
    docker 数据卷 ---- 基础篇
    python做基本的图像处理
    conv1d UpSampling1D aotoencoder 自编码代码摘录
    python daal test
    python dict 构造函数性能比较
    CNN autoencoder 进行异常检测——TODO,使用keras进行测试
    利用CNN进行流量识别 本质上就是将流量视作一个图像
    Deep Belief Network简介——本质上是在做逐层无监督学习,每次学习一层网络结构再逐步加深网络
    python pipe stdout 实现cat|grep 功能
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5647854.html
Copyright © 2011-2022 走看看