图
1.1定义
图(Graph)结构是一种非线性的数据结构。
由一组顶点和一组能够将两个顶点相连的边组成的。
1.2.存储结构
存储结构分两种 一种是邻接矩阵(二维数组)另一种是邻接表
1.2.1邻接矩阵
二维数组索引的值表示顶点 二维数组存储的值表示是否连接 若连接 则存储1 否则存储0
2图的遍历
2.1深度优先遍历
2.1.1例题
P1135 奇怪的电梯
输入格式
共二行。
第一行为33个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1≤N≤200,1≤A,B≤N)。
第二行为NN个用空格隔开的非负整数,表示K_iK
i
。
输出格式
一行,即最少按键次数,若无法到达,则输出-1−1。
输入输出样例
输入 #1复制
5 1 5
3 3 1 2 5
输出 #1复制
3
#include<stdio.h>
int x,y,cnt,m=10000,i,book[1010],a[1010],n,ans;
void dfs(int c)
{
if(cnt>=m)
return;
if(c==y)
{
m=cnt;
return;
}
book[c]=1;
cnt++;
if(c+a[c]<=n&&book[c+a[c]]==0)
dfs(c+a[c]);
if(c-a[c]>=1&&book[c-a[c]]==0)
dfs(c-a[c]);
cnt--;
book[c]=0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)
return 0;
scanf("%d %d",&x,&y);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
dfs(x);
if(m==10000)
printf("-1\n");
else
printf("%d\n",m);}
}
2.1.2例题
题目描述*:小哼走迷宫,从(startx,starty)到(p,q) 求最短路径的步数step
#include<stdio.h>
int min=9999999;
int m,n,p,q;
int book[10][10];
int a[101][101];
void dfs(int x,int y,int step)
{
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int tx,ty,k;
if(x==p&&y==q)
{
if(step<min)
{
//printf("hh");
min=step;
}
return;
}
for(k=0;k<4;k++)
{
// printf("hh");
int tx=x+dir[k][0];
int ty=y+dir[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(book[tx][ty]==0&&a[tx][ty]==0)
{
//printf("hh");
book[tx][ty]=1;
dfs(tx,ty,step+1);
book[tx][ty]=0;
}
}
return ;
}
int main()
{
int sx,sy,i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d %d %d %d",&sx,&sy,&p,&q);
book[sx][sy]=1;
dfs(sx,sy,0);
printf("%d",min);
}
2.1.3例题
题目描述:炸弹放在哪里可以消灭最多的敌人(炸弹杀伤距离超长)
题目解析:从放炸弹的起始点开始遍历右下左上走的每个点可以消灭的敌人数,找出最大的即可
代码实现:
#include<stdio.h>
int max,sum,mx,my,k,n,m,book[101][101]={0};
char a[101][101];
int Sum(int i,int j)
{
int sum,x,y;
sum=0;
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
x--;//向上统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
x++;//向下统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
y--;//向左统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
y++;//向右统计
}
return sum;
}
void dfs(int x,int y)
{
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
sum=Sum(x,y);
if(sum>max)
{
max=sum;
mx=x;
my=y;
}
for(k=0;k<4;k++)
{
int tx=x+next[k][0];
int ty=y+next[k][1];
if(tx<1||tx>n-1||ty<1||ty>m-1)
continue;
if(book[tx][ty]==0&&a[tx][ty]=='.')
{
book[tx][ty]=1;
dfs(tx,ty);
}
return ;
}
}
int main()
{
int i,j,k,tx,ty;
int head,tail,startx,starty;
scanf("%d %d %d %d",&m,&n,&startx,&starty);
for(i=0;i<n;i++)
scanf("%s",a[i]);
book[tx][ty]=1;
max=Sum(startx,starty);
dfs(startx,starty);
printf("%d",max);
getchar();
}
2.3广度优先遍历
2.3.1题目描述:小哼走迷宫,从(startx,starty)到(p,q) 求最短路径的步数step
题目解析:
队列存储坐标再搜素队列中的坐标
#include<stdio.h>
#include<string.h>
struct note
{
int x;
int y;
int s;
int f;
};
int main()
{
struct note que[201];
int a[101][101]={0},book[10][10]={0};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int head,tail;
int startx,starty,m,n,p,q,tx,ty,flag,i,j,k;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d %d %d %d",&startx,&starty,&p,&q);
head=1;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
que[tail].f=0;
que[tail].s=0;
tail++;
book[startx][starty]=1;
flag=0;
while(head<tail)
{
for(k=0;k<=3;k++)
{
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)
{
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].f=head;
que[tail].s=que[head].s+1;
tail++;
}
if(tx==p&&ty==q)
{
// printf("hh");
flag=1;
break;
}
}
if(flag==1)
break;
head++;
}
printf("%d",que[tail-1].s);
getchar();
getchar();
}
2.3.2 炸弹人
题目描述:炸弹放在哪里可以消灭最多的敌人(炸弹杀伤距离超长)
题目解析:从放炸弹的起始点开始遍历右下左上走的每个点可以消灭的敌人数,找出最大的即可
代码实现:
#include<stdio.h>
char a[101][101];
struct note
{
int x;
int y;
int s;
}que[101];
int Sum(int i,int j)
{
int sum,x,y;
sum=0;
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
x--;//向上统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
x++;//向下统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
y--;//向左统计
}
x=i,y=j;
while(a[x][y]!='#')//#代表墙
{
if(a[x][y]=='G')//G代表敌人
sum++;
y++;//向右统计
}
return sum;
}
int main()
{
int n,m,i,j,k,tx,ty,sum,max=0,mx,my;
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int head,tail,startx,starty,book[101][101]={0};
scanf("%d %d %d %d",&m,&n,&startx,&starty);
for(i=0;i<n;i++)
scanf("%s",a[i]);
head=1;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
que[tail].s=0;
tail++;
book[startx][starty]=1;
max=Sum(startx,starty);
mx=startx;
my=starty;
while(head<tail)
{
for(k=0;k<4;k++)
{
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n-1||ty>1||ty>m-1)
continue;
if(book[tx][ty]==0&&a[tx][ty]=='.')
{
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
tail++;
sum=Sum(tx,ty);
if(sum>max)
{
max=sum;
mx=tx;
my=ty;
}
}
}
head++;
}
printf("%d %d",mx,my);
}