数据结构实习-迷宫求解

来源:互联网 发布:电视软件论坛 编辑:程序博客网 时间:2024/05/17 23:33

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

#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;
原创粉丝点击