1. 程式人生 > 其它 >No.5.2 圖的廣度優先遍歷

No.5.2 圖的廣度優先遍歷

重溫一遍 No.4.3 層層遞進-廣度優先搜尋:https://www.cnblogs.com/yalimy/p/15021065.html

/* No.1 廣度優先搜尋,只找出最短路徑層數即可
struct node{
  int x;  //當前節點
  int y;  //層數
};
struct node que[100];
int head=1,tail=1;
int n,m,start,stop;
int cur;
int flag=0;
int a[100][100],book[10]={0};

int main(){
  int i,j;
  int x,y;

  scanf("%d %d %d %d",&n,&m,&start,&stop);

  //初始化圖的二維矩陣

  for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
      if(i==j) a[i][j]=0;
      else a[i][j]=-1;
    }

  for(i=1;i<=m;i++){  //無向圖,對稱矩陣
    scanf("%d %d",&x,&y);
    a[x][y]=1;
    a[y][x]=1;
  }

  que[head].x=start;
  que[head].y=0;
  tail++;
  book[start]=1;

  while(head<tail){
    cur=que[head].x;
    for(i=1;i<=n;i++){
      if(a[cur][i]==1 && book[i]==0){
        book[i]=1;
        que[tail].x=i;
        que[tail].y=que[head].y+1;
        tail++;
        if(i==stop){
          flag=1;
          break;
        }
      }
    }
    if(flag==1){
      break;
    }
    head++;
  }
  printf("%d",que[tail-1].y);
  getchar();getchar();return 0;
}
*/

/* No2. 廣度優先演算法:列印最短路徑
struct node{
  int x;   //當前節點
  int y;   //父節點值
  int s;   //步數
};
struct node que[100];
int head=1,tail=1;
int n,m,start,stop;
int cur,hd;
int flag=0;
int a[100][100],book[10]={0};

int main(){
  int i,j;
  int x,y;

  scanf("%d %d %d %d",&n,&m,&start,&stop);

  for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
      if(i==j) a[i][j]=0;
      else a[i][j]=-1;
    }

  for(i=1;i<=m;i++){
    scanf("%d %d",&x,&y);
    a[x][y]=1;
    a[y][x]=1;
  }

  que[head].x=start;
  que[head].y=0;
  que[head].s=0;
  tail++;
  book[start]=1;


  hd=head; //使用臨時變數,防止 que[head] 真的被釋放
  while(head<tail){
    cur=que[hd].x; // hd 移動時,cur的值隨之改變
    for(i=1;i<=n;i++){
      if(a[cur][i]==1 && book[i]==0){
        book[i]=1;
        que[tail].x=i;
        que[tail].y=que[cur].x;
        que[tail].s=que[cur].s+1;
        tail++;
        if(i==stop){
          flag=1;
          break;
        }
      }
    }
    if(flag==1){
      break;
    }
    hd++; //指標前移
  }
  printf("最少遍歷次數:%d\n",que[tail-1].s);
  printf("遍歷節點如下:\t");
  for(i=head;i<tail;i++)
    printf("(%d,%d,%d)\t",que[i].x,que[i].y,que[i].s);

  printf("\n最短路徑為:(%d,%d,%d)\t",que[tail-1].x,que[tail-1].y,que[tail-1].s);
  cur=tail-1;
  for(i=cur-1;i>=head;i--){
    if(que[i].x==que[cur].y && que[i].s==que[cur].s-1){
      printf("(%d,%d,%d)\t",que[i].x,que[i].y,que[i].s);
      cur=i; //通過 cur 實現自我遞迴!
    }
    else
      continue;
  }
  getchar();getchar();return 0;
}
*/

/* No3. 廣度優先演算法:列印最短路徑
struct node{
  int x;   //當前節點
  int y;   //指向父節點所在佇列的索引位置
  int s;   //步數
};
struct node que[100];
int head=1,tail=1;
int n,m,start,stop;
int cur,hd;
int flag=0;
int a[100][100],book[10]={0};

int main(){
  int i,j;
  int x,y;

  scanf("%d %d %d %d",&n,&m,&start,&stop);

  for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
      if(i==j) a[i][j]=0;
      else a[i][j]=-1;
    }

  for(i=1;i<=m;i++){
    scanf("%d %d",&x,&y);
    a[x][y]=1;
    a[y][x]=1;
  }

  que[head].x=start;
  que[head].y=0;
  que[head].s=0;
  tail++;
  book[start]=1;


  hd=head;
  while(head<tail){
    cur=que[hd].x;
    for(i=1;i<=n;i++){
      if(a[cur][i]==1 && book[i]==0){
        book[i]=1;
        que[tail].x=i;
        que[tail].y=hd;    //父節點所在佇列的索引下標
        que[tail].s=que[cur].s+1;
        tail++;
        if(i==stop){
          flag=1;
          break;
        }
      }
    }
    if(flag==1){
      break;
    }
    hd++;
  }


  printf("最少遍歷次數:%d\n",que[tail-1].s);
  printf("遍歷節點如下:\t");
  for(i=head;i<tail;i++)
    printf("(%d,%d,%d)\t",que[i].x,que[i].y,que[i].s);

  printf("\n最短路徑為:(%d,%d,%d)\t",que[tail-1].x,que[tail-1].y,que[tail-1].s);
  cur=tail-1;
  while(cur>head){    //注意,這裡是大於head!
    cur=que[cur].y;    //直接找到父節點的索引座標
    printf("(%d,%d,%d)\t",que[cur].x,que[cur].y,que[cur].s);
  }
  getchar();getchar();return 0;
}
*/