神秘国度的爱情故事

题目:某个太空神秘国度中有很多美丽的小村,从太空中可以望见,小村间有路相连,更精确点说,任意两村之间有且仅有一条路径。 
小村A中有位年轻人爱上了自己村里美丽姑娘。每天早晨,姑娘都要去小村B里的面包房工作,傍晚6点回家。年轻人终于决定要向姑娘表白,他打算在小村C等着姑娘路过的时候把爱慕说出来。问题是,他不能确定小村C是否在小村B到小村A之间的路径上。你可帮助他解决这个问题吗
input
3
0 1
1 2
3
0 2 1
1 2 0
1 2 1
0
output
Yes
No
Yes





代码如下:
#include<iostream>
using namespace std;
#define MAXNODE 50000 //图中顶点的最大个数

typedef struct arc //边的邻接点
  {int adjvex; //邻接点在顶点向量中的下表
  struct arc *next; //指向下一邻接点的指针
}ArcNode; 
   
typedef struct VexNode //顶点结点(村子)
{int vertex; //顶点信息(村子编号)
 ArcNode *firstarc;//指向第一邻接点的指针
}VerNode;

typedef VerNode AdjList[MAXNODE];//邻接表

int visited[MAXNODE];

int vexnum,arcnum;//顶点和边的个数

void creatgraph(AdjList GL)//创建一个村落图
{int i,j,k,n;
 ArcNode *p;
 cout<<"请输入村子的个数 N :"<<endl;
 cin>>n;
 vexnum=n;
 arcnum=n-1;//边数是村子数-1
 for(i=0;i<vexnum;i++)//每个小村从0到N-1编号
  {GL[i].vertex=i;
  GL[i].firstarc=NULL;
  }
//接下来有N-1行输入,每行包含一条双向的两个端点小村的编号,中间用空格分开。
cout<<"请输入村子的"<<n-1<<"条路径(两个端点中间用空格分隔):"<<endl;
 for(k=0;k<arcnum;k++)
  {cin>>i>>j;
  //下面完成邻接表的建立
p=new ArcNode;
  p->adjvex=j;p->next=GL[i].firstarc;GL[i].firstarc=p;//类似于头插法
  p=new ArcNode;
  p->adjvex=i;p->next=GL[j].firstarc; GL[j].firstarc=p;//路径是双向的
  }//for
 }


void BfsAdjTree2(AdjList GL,int a,int b)  
{//广度遍历邻接表,并查询b是否在a到所有未访问结点的路径上 
 int k,Q[MAXNODE],front=0,rear=0;//使用队列
 int i=0;
 ArcNode *p; //指向边结点的指针
 visited[a]=1; //A村子开始所有访问过的村子标志为1
 rear=(rear+1)%MAXNODE;//计算队列尾所在位置
 Q[rear]=a;//从a村子开始
 while(front!=rear)//判队空
 {
  front=(front+1)%MAXNODE;//计算队列头所在位置
  k=Q[front];
  p=GL[k].firstarc;
  while(p!=NULL&&i!=1)//是否为最后一个边结点
  {if(!visited[p->adjvex])//结点是否被访问过
  {visited[p->adjvex]=1;//标记已访问
  if(p->adjvex==b)//如果遍历到b
{
  cout<<"yes"<<endl;
  i=1;
  rear=front;
  }
   
  if(i!=1)
  {
  rear=(rear+1)%MAXNODE;
  Q[rear]=p->adjvex;
  }
  }//为访问的结束 
  p=p->next;
 }//判指针为空结束 
}//判队列空结束
if(i!=1)
cout<<"no"<<endl; 
}
 
int BfsAdjTree1(AdjList GL,int a,int b,int c)  
{//广度遍历邻接表,并查询c是否在a,b之间的路径上
 int k,Q[MAXNODE],front=0,rear=0;//使用队列
 int i=0;
 ArcNode *p; //指向边结点的指针
 visited[a]=1; //A村子开始所有访问过的村子标志为1
 rear=(rear+1)%MAXNODE;//计算队列尾所在位置
 Q[rear]=a;//从a村子开始
 while(front!=rear)//判队空
 {
  front=(front+1)%MAXNODE;//计算队列头所在位置
  k=Q[front];
  p=GL[k].firstarc;
  while(p!=NULL&&i!=1)//是否为最后一个边结点
  {if(!visited[p->adjvex])//结点是否被访问过
  {visited[p->adjvex]=1;//标记已访问
  if(p->adjvex==b)//如果遍历到b
{
  cout<<"no"<<endl;
  i=1;
front=rear;
  }
  else 
  {if(p->adjvex==c)//如果遍历到c
{
  BfsAdjTree2(GL,c,b);
i=1;
front=rear;
  }
  }
  if(i==0)
  {
  rear=(rear+1)%MAXNODE;
  Q[rear]=p->adjvex;
  }
  }//为访问的结束 
  p=p->next;
 }//判指针为空结束 
}//判队列空结束 
}
 

int main( )

  cout<<"***********************************************"<<endl;
  cout<<" 神秘国度的爱情故事"<<endl;
  cout<<"***********************************************"<<endl<<endl;
  AdjList GL;
  int m,i,j;
  int text1[MAXNODE],text2[MAXNODE],text3[MAXNODE];//用于存放测试组
  creatgraph(GL);
  cout<<"请输入你有多少测试组?"<<endl;
  cin>>m;
  cout<<"请输入你要测试的A B C三村的编号:"<<endl;
  for(i=0;i<m;i++)
  cin>>text1[i]>>text2[i]>>text3[i];
  cout<<"测试后的结果为:"<<endl;
  for(i=0;i<m;i++)
  {if(text1[i]==text3[i]||text2[i]==text3[i])
  cout<<"yes"<<endl;
  else
  {
  for(j=0;j<vexnum;j++) 
  visited[j]=0; //所有未访问村子标志为0
  BfsAdjTree1(GL,text1[i],text2[i],text3[i]);
  }
  }
  return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值