您的位置:首页 > 理论基础 > 数据结构算法

数据结构实习-迷宫求解

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: