hdu1548A strange lift——最短路(迪傑斯特拉,spfa)。bfs(隊列。數組)

題意:有n層電梯,當前處於A層,要到B層去,然後給你n個數,代表處在i層時會向下或者上走a[i]層,即到達i+a[i]或i-a【i】,求最小按電梯的次數(上下移動次數);

思路:簡單題,沒有什麼思路,用最短路的Dijkstra和spfa就是簡單地模板,兩個bfs也挺簡單。

我用四中方法做的,

首先是隊列模擬bfs

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[250];//記錄每層電梯上下的層數 
int n,s,e;//n層,s是起始層,e是終止層 
int mark[250];
int step[250];//記錄到i層要step【i】步 
int loc[250];//沒有隊列,就用這個數組模擬隊列,存放走過的 
void bfs()
{
	int length,tail;
	length=1;//增加和表示“隊列”的長度 
	tail=0;//在數組裏取出下一個數 
	loc[0]=s;
	while(length>tail)
	{
		int x=loc[tail++];
		if(x==e)
		{
			printf("%d\n",step[x]);
			return;
		}
		int up=x+a[x];
		if(mark[up]==0&&up>=1&&up<=n)
		{
			loc[length++]=up;
			mark[up]=1;
			step[up]=step[x]+1;
		}
		int down=x-a[x];
		if(mark[down]==0&&down>=1&&down<=n)
		{
			loc[length++]=down;
			mark[down]=1;
			step[down]=step[x]+1;
		}
	}
	printf("-1\n");
}
int main()
{
	
	while(scanf("%d",&n)!=EOF)
	{
		if(n<=0) break;
		scanf("%d%d",&s,&e);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			step[i]=0;
			mark[i]=0;
		}
		if(s==e)
		{
			printf("0\n");
			continue;
		}
		bfs();
	}
	return 0;
}

bfs隊列做法:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[250];//記錄每層電梯上下的層數 
int mark[250];
int step[250];//記錄到i層要step【i】步 
int n,s,e;//n層,s是起始層,e是終止層 
void bfs()
{
	queue<int>q;
	int x,down,up;
	while(!q.empty()) q.pop();
	q.push(s);
	while(!q.empty())
	{
		x=q.front();
		q.pop();
		if(x==e)
		{
			printf("%d\n",step[x]);
			return;
		}
		up=x+a[x];
		if(up>=1&&up<=n&&mark[up]==0)
		{
			q.push(up);
			mark[up]=1;
			step[up]=step[x]+1;
		}
		down=x-a[x];
		if(down>=1&&down<=n&&mark[down]==0)
		{
			q.push(down);
			mark[down]=1;
			step[down]=step[x]+1;
		}
	}
	printf("-1\n");
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n<=0) break;
		scanf("%d%d",&s,&e);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			step[i]=0;
			mark[i]=0;
		}
		if(s==e)
		{
			printf("0\n");
			continue;
		}
		bfs();
		
	}
	return 0;
}
迪傑斯特拉做法:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define inf 5000;
using namespace std;
int n,s,e;
int a[250];
int dis[250];
int map[250][250];
int mark[250];
void Dijkstra()
{
	for(int i=1;i<=n;i++)
	{
		dis[i]=map[s][i];
		mark[i]=0;
	}
	for(int i=1;i<=n;i++)
	{
		int x,m=inf;
		for(int j=1;j<=n;j++)
		{
			if(dis[j]<m&&mark[j]==0)
			{
				m=dis[j];
				x=j;
			}
		}
		mark[x]=1;
		for(int j=1;j<=n;j++)
		{
			if(dis[x]+map[x][j]<dis[j]&&mark[j]==0)
			{
				dis[j]=dis[x]+map[x][j];
			}
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n<=0) break;
		scanf("%d%d",&s,&e);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				map[i][j]=inf;
			}
		}
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if(i+a[i]>=1&&i+a[i]<=n)
			{
				map[i][i+a[i]]=1;
			}
			if(i-a[i]>=1&&i-a[i]<=n)
			{
				map[i][i-a[i]]=1;
			}
		}
		if(s==e)
		{
			printf("0\n");
			continue;
		}
		Dijkstra();
		if(dis[e]==5000)
		{
			printf("-1\n");
		}
		else
		{
			printf("%d\n",dis[e]);
		}
	}
	return 0;
}

spfa做法:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define inf 50000
using namespace std;
struct node
{
	int next;
	int to;
	int weight;
}life[550];
int mark[250];
int dis[250];
int head[250];
int a[250];
int n,s,e;int cur;
void init()
{
	cur=1;
	memset(head,-1,sizeof(head));
	memset(life,0,sizeof(life));
	for(int i=1;i<=n;i++)
	{
		dis[i]=inf;
		mark[i]=0;
	}
}
void add(int u,int v)
{
	life[cur].to=v;
	life[cur].weight=1;
	life[cur].next=head[u];
	head[u]=cur;
	cur++;
}
void spfa_bfs()
{
	queue<int>q;
	int first,i;
	while(!q.empty()) q.pop();
	q.push(s);
	dis[s]=0;
	mark[s]=1;
	while(!q.empty())
	{
		first=q.front();
		q.pop();
		mark[first]=0;
		for(i=head[first];i!=-1;i=life[i].next)
		{
			if(life[i].weight+dis[first]<dis[life[i].to])
			{
				dis[life[i].to]=life[i].weight+dis[first];
				if(mark[life[i].to]==0)
				{
					q.push(life[i].to);
					mark[life[i].to];
				}
			}
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n<=0) break;
		init();
		scanf("%d%d",&s,&e);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if(i+a[i]<=n)
			add(i,i+a[i]);
			if(i-a[i]>=1)
			add(i,i-a[i]);
		}
		if(s==e)
		{
			printf("0\n");
			continue;
		}
		spfa_bfs();
		if(dis[e]>=inf)
		{
			printf("-1\n");
		}
		else
		{
			printf("%d\n",dis[e]);
		}
	}
	return 0;
}


發佈了54 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章