数据结构实习-迷宫求解
2017-07-13 21:46
197 查看
我的思路是。
先广搜出最短的那个出口,然后在把每个广搜路过的点中,每一个和四周的点见一条边(起点除外),然后出口再向起点建一条边,然后在进行强连通分量的分解。但是后来我发现,即使是这样也会造成多余的点(即显示最短路径时显示了其他的点。)
后来我的思路是枚举起点四个方向建一条边,然后求点最少的情况。
先广搜出最短的那个出口,然后在把每个广搜路过的点中,每一个和四周的点见一条边(起点除外),然后出口再向起点建一条边,然后在进行强连通分量的分解。但是后来我发现,即使是这样也会造成多余的点(即显示最短路径时显示了其他的点。)
后来我的思路是枚举起点四个方向建一条边,然后求点最少的情况。
#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;
相关文章推荐
- 数据结构实习:迷宫求解
- 数据结构实习-迷宫(基于Qt实现)
- 数据结构-->迷宫-->递归求解
- 数据结构(迷宫求解c++)
- 数据结构的应用——使用栈实现任意迷宫的求解
- 【数据结构】算法3.3 迷宫求解
- 数据结构(迷宫求解c++)
- 数据结构和算法设计(迷宫求解问题的栈和队列的实现)
- 数据结构--用栈求解迷宫问题(非最优解)
- 数据结构:栈的应用(迷宫的求解)
- JS手撸数据结构系列 (五) ——图的遍历与迷宫求解
- 数据结构-迷宫求解路径
- [数据结构]求解迷宫最短路径问题
- 【数据结构】迷宫问题求解(链栈,DFS)
- 数据结构的应用------------迷宫求解
- (数据结构)栈_迷宫求解(严蔚敏P50) _模仿
- 【数据结构】递归求解迷宫问题
- 数据结构中的栈,在解决很多问题都有用处,比如括号匹配,迷宫求解,表达式求值等等 java中有封装好的类,可以直接调用。
- 【数据结构】用回溯法求解迷宫问题
- 《数据结构》(C语言版)——栈的应用举例-迷宫求解