周报(水管工问题,和图的遍历)

枯木逢春不在茂,年少且惜镜边人

这周继续完成上周么有完成的目标,然后学学java,学学图的遍历,学学浴谷上的题,然后上天.
1.水管工问题

#include<stdio.h>
int book[51][51];
int a[51][51],n,m,flag=0;
struct note
{
	int x;
	int y;
} s[100];
int top=0;
void dfs(int x,int y,int front)
{
	int i;
	if(x==n&&y==m+1)
	{
		flag=1;
		for(i=1;i<=top;i++)
		printf("(%d,%d)",s[i].x,s[i].y);
	}
	if(x<1||x>n||y<1||y>m)
	return ;
	if(book[x][y]==1)
	return ;
	book[x][y]=1;
	top++;
	s[top].x=x;
	s[top].y=y;
	if(a[x][y]>=5&&a[x][y]<=6)
	{
		if(front==1)
		dfs(x,y+1,1);
		if(front==2)
		dfs(x+1,y,2);
		if(front==3)
		dfs(x,y-1,3);
		if(front==4)
		dfs(x-1,y,4);
	}
	if(a[x][y]>=1&&a[x][y]<5)
	{
		if(front==1)//左 
		{
			dfs(x+1,y,2);
			dfs(x-1,y,4);
		}
		if(front==2)//上 
		{
			dfs(x,y-1,3);
			dfs(x,y+1,1);
		}
		if(front==3)//右 
		{
			dfs(x-1,y,4);
			dfs(x+1,y,2);

		}
		if(front==4)//下 
		{
			dfs(x,y-1,3);
			dfs(x,y+1,1);
		}
	}
	book[x][y]=0;
	top--;
	return ;
}
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	 for(j=1;j<=m;j++)
	  scanf("%d",&a[i][j]);
	dfs(1,1,1);
	if(flag==0)
	printf("impossible\n");
	return 0; 
}

在这里插入图片描述在这里插入图片描述1 2 3 4 5 6 分别代表水管子的6种情况
详细请看这位大佬1 2 3 4 5 6 的表示什么
用dfs,从两个方面进行判断,看是不是直管子或者弯管子,这样就可以从4个方向判断进水口位置,然后用(n,m+1)判断结束,为什么是M+1,因为最后是从最右边出,所以最后肯定是(X,Y+1,1),所以就是M+1了
其他的就是用栈来储存路径,然后就是DFS模板!
**
2.今天来看一下林某人口中最基本最基本的图的遍历
首先看一下无向图用dfs解决

#include<stdio.h>
int book[101],sum,n,e[101][101];
void dfs(int cur)
{
 int i;
 printf("%d",cur);
 sum++;
 if(sum==n)
 return ;
 for(i=1;i<=n;i++)
 {
  if(e[cur][i]==1&&book[i]==0)
  {
   book[i]=1;
     dfs(i);
  }
 }
 return ;
}
int main()
{
 int i,j,m,a,b;
 scanf("%d %d",&n,&m);
 for(i=1;i<=n;i++)
  for(j=1;j<=n;j++)
  {
   if(i==j)
   e[i][j]=0;
   else
   e[i][j]=99999999;
  }
 for(i=1;i<=m;i++)
 {
  scanf("%d %d",&a,&b);
  e[a][b]=1;
  e[b][a]=1;
 }
 book[1]=1;
 dfs(1);
 return 0;
} 

数据5 5 1 2 1 3 1 5 2 4 3 5
运行结果1 2 4 3 5
二维数组存储图
每一行就是一个点,这一行中的列就是这个点连接另一个
在解决这个问题的同时,林某人也指出了一个问题
我先学着,学着在回来看
这是一个遍历顺序,当然遍历顺序是根据代码的不同而不同,所有的遍历顺序是一个序列
当然这这就是BFS和DFS的区别
看看bfs遍历图吧

#include<stdio.h>
int book[101];
int main()
{
 int e[101][101],n,m,i,j,a,cur,b;
 int que[10001],head,tail;
 scanf("%d %d",&n,&m);
  for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)
    {
     if(i==j)
     e[i][j]=0;
     else
     e[i][j]=99999999;
    }
  for(i=1;i<=m;i++)
  {
   scanf("%d %d",&a,&b);
   e[a][b]=1;
   e[b][a]=1;
  }
  head=1;
  tail=1;
  que[head]=1;
  tail++;
  book[1]=1;
  while(head<tail&&tail<=n)
  {
   cur=que[head];
   for(i=1;i<=n;i++)
   {
    if(e[cur][i]==1&&book[i]==0)
    {
     book[i]=1;
    que[tail]=i;
    tail++; 
    }
    if(tail>n)
    {
     break;
    }
   }
  head++;
  } 
  for(i=1;i<tail;i++)
  printf("%d ",que[i]);
 return 0;
 } 

在这里插入图片描述这就是bfs遍历邻接矩阵,其中序列有很多,但是本代码的搜索顺序是这样的,所以你可以有很多种方法搜索,但是需要修改其中的一些条件…
下来看看城市地图的搜索---------dfs.
首先看一下有向图

在这里插入图片描述这个题,找1-5 的最短路径,并输出
直接看代码

#include<stdio.h>
int n,m,a,b,c,min=999999;
int book[101],e[101][101];
void dfs(int cur,int dis) 
{
	int j;
	if(dis>min)
	return ;
	if(cur==n)
	{
		if(dis<min)
		min=dis;
		return ;
	}
	
	for(j=1;j<=n;j++)
	{
		if(e[cur][j]!=99999999&&book[j]==0)
		{
			book[j]=1;
			dfs(j,dis+e[cur][j]);
			book[j]=0;
		}
	}
	return ;
}
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	 for(j=1;j<=n;j++)
	 {
	 	if(i==j)
	 	e[i][j]=0;
	 	else
	 	e[i][j]=99999999;
	 }
	 for(i=1;i<=m;i++)
	 {
	 	scanf("%d %d %d",&a,&b,&c);
	 	e[a][b]=c;
	 }
	 book[1]=1;
	 dfs(1,0);
	 printf("%d",min);
	 return 0;
}

在这里插入图片描述输入的数据如下
那么问题来了,无向图的代码怎么改,只需要把邻接矩阵a[i][j]=a;a[j][i]=a
下来请看代码

#include<stdio.h>
int n,m,a,b,c,min=999999;
int book[101],e[101][101];
void dfs(int cur,int dis) 
{
	int j;
	if(dis>min)
	return ;
	if(cur==n)
	{
		if(dis<min)
		min=dis;
		return ;
	}
	
	for(j=1;j<=n;j++)
	{
		if(e[cur][j]!=99999999&&book[j]==0)
		{
			book[j]=1;
			dfs(j,dis+e[cur][j]);
			book[j]=0;
		}
	}
	return ;
}
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	 for(j=1;j<=n;j++)
	 {
	 	if(i==j)
	 	e[i][j]=0;
	 	else
	 	e[i][j]=99999999;
	 }
	 for(i=1;i<=m;i++)
	 {
	 	scanf("%d %d %d",&a,&b,&c);
	 	e[a][b]=c;
	 	e[b][a]=c;
	 }
	 book[1]=1;
	 dfs(1,0);
	 printf("%d",min);
	 return 0;
}

在这里插入图片描述我们可以发现这里最短路径变成了7,这是因为无向图,路径比较灵活,所以大家可以看看这个图。
好的,下面我们就看看
最少转机–图的广度优先遍历

比如这个无向图

1------ ------2
\ /
\ /|
\ / |
3 |
/ \ |
/ \ |
/ \ |
5---------4
这次我们用宽搜来写的
好了详细请看代码

#include<stdio.h>
struct f
{
	int x;
	int s;
};
int main()
{
	int m,n,a,b,c;
	int book[51]={0};
	int head,tail;
	struct f que[2501];
	int i,j,cur,start,end,flag=0,e[51][51]={0};
	head=1;
	tail=1;
	scanf("%d %d %d %d",&n,&m,&start,&end);
	for(i=1;i<=n;i++)
	 for(j=1;j<=n;j++)
	 {
	 	if(i==j)
	 	e[i][j]=0;
	 	else
	 	e[i][j]=99999999;
	 }
	for(i=1;i<=m;i++)
	{
		scanf("%d %d",&a,&b);
		e[a][b]=1;
		e[b][a]=1;
	}
	que[tail].x=start;
	que[tail].s=0;
	tail++;
	book[start]=1;
	while(head<tail)
	{
		cur=que[head].x;
		for(j=1;j<=n;j++)
		{
			if(e[cur][j]!=99999999&&book[j]==0)
			{
				que[tail].x=j;
				que[tail].s=que[head].s+1;
				tail++;
				book[j]=1;
			}
			if(que[tail-1].x==end)
			{
				flag=1;
				break;
			}
		}
		if(flag==1)
		break;
		head++;
	}
	printf("%d",que[tail-1].s);
	return 0;
}

在这里插入图片描述这便是最少转机—图的广度优先遍历
都是最基础的
大佬莫怪
好了下面就看看只有五行的算法------Floyd-Warshall

基本的图的遍历就这样,下下周再学习二叉树
下周就是最短路径----------(各种算法,动态规划!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值