数据结构实习-迷宫求解

我的思路是。
先广搜出最短的那个出口,然后在把每个广搜路过的点中,每一个和四周的点见一条边(起点除外),然后出口再向起点建一条边,然后在进行强连通分量的分解。但是后来我发现,即使是这样也会造成多余的点(即显示最短路径时显示了其他的点。)
后来我的思路是枚举起点四个方向建一条边,然后求点最少的情况。

#include <bits/stdc++.h>
using namespace std;
typedef int stack_kind;
typedef int queue_kind;
const int stack_size=200;
const int queue_size=200;
const int maxn=200;
char a[maxn][maxn];
int fx[2][4]{{1,-1,0,0},{0,0,-1,1}};//广搜的方向搜索。
bool vis[maxn][maxn];
vector<int>G[maxn];//存图用的。
int limit;//在转换图的过程中用来 确定映射点的最大范围。
int graph_node;
bool vis2[maxn];
bool vis4[5][maxn][maxn];
struct queue1{
   int front1;
   int rear1;
  queue_kind num[maxn];
   queue1(){
      front1=0;rear1=0;
      memset(num,0,sizeof(num));
   }
public :bool empty(){
    if(front1==rear1)
       return true;
       return false;
}
 public:int  front(){

    if(front1==rear1){
         //cout<<front1<<" "<<rear1<<endl;
         puts("wrong manner!");
        return -1;
    }
    return num[front1];
}
public :bool pop(){
     front1++;
}
public : void push(queue_kind  s){
   num[rear1++]=s;
   //cout<<front1<<endl;
}
};
struct Stack{
     stack_kind num[maxn];
     int top1;
     int base;
public :void push(stack_kind m){
      num[top1++]=m;
}
public:void pop(){
  top1--;
}
public:bool empty(){
   if(top1==base+1)
      return true;
      return false;
}
public :stack_kind top(){
   if(top1==base){
       puts("unknown wrong");
       return -1;
   }
   return num[top1-1];
}
Stack(){
   top1=1;base=0;
   memset(num,0,sizeof(num));
}
};
int upper_x;
int upper_y;
int cnt[maxn];
int num[maxn];
int scc;
stack<int>s;
int dfn[maxn];//dfs顺序。和一种求lca的序不一样??
int low[maxn];//最小能够到达的点。
int index1;//记录时间的标号
bool state[maxn];//是否在栈里.
void tarjan(int u)
{  dfn[u]=low[u]=++index1;
   s.push(u);
   state[u]=true;
   for(int i=0;i<G[u].size();i++){
       if(!dfn[G[u][i]]){
          tarjan(G[u][i]);
          low[u]=min(low[G[u][i]],low[u]);
       }
       else if(state[G[u][i]])
         low[u]=min(low[u],dfn[G[u][i]]);//在次遇见你。。
   }
   if(low[u]==dfn[u])
    {
        scc++;
        for(;;)
        {
            int x = s.top();s.pop();
            cnt[x]=scc;
            num[scc]++;
            if(x==u)break;
        }
    }
}
int main()
{   ios::sync_with_stdio(false);
    bool flag;
    int m,n;
    while(cin>>n>>m)
    {flag=false;
    Stack s1;
    Stack s2;
    queue1 q1;
    queue1 q2;
    for(int i=1;i<=n;i++){
       for(int j=1;j<=m;j++){
           cin>>a[i][j];
           if(a[i][j]=='1'){
              q1.push(i);
              q2.push(j);
              flag=true;
           }
       }
    }
    if(!flag){
        puts("没有1唉,1是起点好伐");
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
        cout<<a[i][j]<<"  ";
        cout<<endl;
    }
    memset(vis,false,sizeof(vis));
    bool flag=false;
    cout<<q1.front()<<endl;
    cout<<q2.front()<<endl;
    int a1[maxn];
    int a2[maxn];
    int kk=0;
   while(!q1.empty()&&!q2.empty()){
       int u1=q1.front();q1.pop();
       int u2=q2.front();q2.pop();
       s1.push(u1);
       s2.push(u2);
       //cout<<u1<<" "<<u2<<endl;
       if(u1==1||u1==n||u2==1||u2==m)
                  {flag=true;break;}
       for(int i=0;i<4;i++){
           int x1=u1+fx[1][i];
           int y1=u2+fx[0][i];
           //cout<<x1<<" ###3"<<y1<<endl;
           if(!vis[x1][y1]&&a[x1][y1]=='.'&&x1>=1&&x1<=n&&y1>=1&&y1<=m){
              vis[x1][y1]=true;
               //cout<<x1<<"??"<<y1<<endl;
              q1.push(x1);
              q2.push(y1);
           }
       }
    }
    memset(vis,false,sizeof(vis));
     if(flag)
        puts("YES");
      else
        puts("NO");
          if(flag){
          puts("下面输入地址的路径");
          int kk=0;
          while(!s1.empty()&&!s2.empty()){
           /*cout<<s1.top()<<" "<<s2.top()<<endl;
            s1.pop();s2.pop();*/
             a1[kk]=s1.top();s1.pop();
             a2[kk++]=s2.top();s2.pop();
             cout<<" "<<a1[kk-1]<<" "<<a2[kk-1]<<endl;
         }
         upper_x=0;
         upper_y=0;
         for(int i=0;i<kk;i++){
            a1[i]-=upper_x;;
            a2[i]-=upper_y;
            //upper_x=max(upper_x,a1[i]*m+a2[i]);
            //upper_y=max(upper_y,a2[i]);
         }
         memset(vis4,false,sizeof(vis4));
         int bigx=0;
         int big=0x3f3f3f3f;
        for(int xxx=1;xxx<=4;xxx++){
           for(int i=0;i<maxn;i++)
              G[i].clear();
              if(xxx==1)
         G[a1[kk-1]*m+a2[kk-1]].push_back(a1[kk-1]*m+1+a2[kk-1]);
         else if(xxx==2)
          G[a1[kk-1]*m+a2[kk-1]].push_back(a1[kk-1]*m+a2[kk-1]+m);
          else if(xxx==3)
          G[a1[kk-1]*m+a2[kk-1]].push_back(a1[kk-1]*m+a2[kk-1]-1);
          else if(xxx==4)
           G[a1[kk-1]*m+a2[kk-1]].push_back(a1[kk-1]*m+a2[kk-1]-m);
         for(int i=0;i<kk-1;i++){
            if(a1[i]*m+1+a2[i]>=0)
            G[a1[i]*m+a2[i]].push_back(a1[i]*m+1+a2[i]);
            if(a1[i]*m+a2[i]+m>=0)
             G[a1[i]*m+a2[i]].push_back(a1[i]*m+a2[i]+m);
             if(a1[i]*m+a2[i]-1<=0)
             G[a1[i]*m+a2[i]].push_back(a1[i]*m+a2[i]-1);
             if(a1[i]*m+a2[i]-m<=0)
             G[a1[i]*m+a2[i]].push_back(a1[i]*m+a2[i]-m);

         }
         G[a1[0]*m+a2[0]].push_back(a1[kk-1]*m+a2[kk-1]);
     //cout<<kk<<"!!"<<endl;
     limit=-1;
     for(int i=0;i<kk;i++){
         limit=max(limit,a1[i]*m+a2[i]);
      }
            /*for(int i=0;i<=limit;i++){
            {   cout<<"@@@ "<<i<<" ";
                for(int j=0;j<G[i].size();j++){
                cout<<G[i][j]<<" ";
            }
            cout<<endl;
            }
            }*/
      memset(state,false,sizeof(state));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(cnt,0,sizeof(cnt));//tarjan的初始化.
    memset(vis2,false,sizeof(vis2));
    index1=0;
       graph_node=a1[kk-1]*m+a2[kk-1];
        int sum=0;
        for(int i=0;i<=limit;i++){
            if(!dfn[i])
             tarjan(i);
        }
        for(int i=0;i<=limit;i++){
           if(cnt[i]==cnt[graph_node])
              {vis2[i]=true;sum++;}
              //printf("%d   %d!!!!!!!!\n",xxx,cnt[i]);
        }
        //cout<<cnt[graph_node]<<"??"<<endl;
                int first,second;
        for(int i=0;i<=limit;i++){
           if(vis2[i]==true)
             {first=i/m;
             second=i%m;
             vis4[xxx][first+upper_x][second+upper_y]=true;
             }
        }
          if(sum<big&&sum!=0&&sum!=1&&vis4[xxx][a1[kk-1]][a2[kk-1]]&&vis4[xxx][a1[0]][a2[0]]){
            bigx=xxx;
            big=sum;
          }
          /*cout<<xxx<<"!!!!!"<<sum<<endl;
           for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
               if(vis4[xxx][i][j])
                 cout<<"1"<<" ";
                 else
                 cout<<"0"<<" ";
            }
            cout<<endl;
        }*/
        }
         //tarjan();
        // cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<bigx<<" !!"<<endl;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
               if(vis4[bigx][i][j])
                 cout<<"1"<<" ";
                 else
                 cout<<"0"<<" ";
            }
            cout<<endl;
        }
        }
        else
        {  puts("在修炼几年吧。哈哈");
        }
    }
    return 0;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值