第二周实验A 图论 bfs

题目在这里插入图片描述假设如上图,这个烷烃基有6个原子和5个化学键,6个原子分别标号1~6,然后用一对数字 a,b 表示原子a和原子b间有一个化学键。这样通过5行a,b可以描述一个烷烃基

你的任务是甄别烷烃基的类别。
原子没有编号方法,比如

1 2

2 3

3 4

4 5

5 6

1 3

2 3

2 4

4 5

5 6
是同一种,本质上就是一条链,编号其实是没有关系的,可以在纸上画画就懂了
输入:
输入第一行为数据的组数T(1≤T≤200000)。每组数据有5行,每行是两个整数a, b(1≤a,b≤6,a ≤b)
数据保证,输入的烷烃基是以上5种之一
输出:
每组数据,输出一行,代表烷烃基的英文名
样例:
输入:
2
1 2
2 3
3 4
4 5
5 6
1 4
2 3
3 4
4 5
5 6
输出:
n-hexane
3-methylpentane

首先要观察这几个分子的特点,其中n-hexane;2,3-dimethylbutane和2,2-dimethylbutane有很明显的特点,他们的点的度数都是独一无二的,而2-methylpentane和3-methylpentane都是有一个度数为3的点,不容易区分,需要特别处理。
这一题先用bfs来求出每个点的度数,其中flag数组是用来记录度数的。

 queue q;
 reach[a]=1;
 q.push(a);
 while(!q.empty())
 {
  int b=q.front();
  q.pop();
  
  for(int i=1;i<7;i++)
  {
   if(table[i][b]==1)//该边未经过
   if(reach[i]==0)
   {
    flag[b]++;//该边的两个点的度数都加1
    flag[i]++;
    reach[i]=1;
    q.push(i); 
   }
  }
 }

根据点的度数判断并输出

int count2=0,count3=0,count1=0;
 for(int i=1;i<7;i++)
 {
  if(flag[i]==4)//有点的度数是4,则必定是2,2-dimethylbutane
  {
   cout<<"2,2-dimethylbutane"<<'\n';
   return;
  }
  else if(flag[i]==2)//记录度数为2的点的数目
  {
   count2++;
  }
  else if(flag[i]==3)//记录度数为3的点的数目
  {
   count3=i;
  }
  else if(flag[i]==1)//记录度数为1的点的数目
  {
   count1++;
  }
 }
 if(count2==4)//如果度数为2的点的数目为4则必定为n-hexane
 {
  cout<<"n-hexane"<<'\n';
  return;
 }
 if(count1==4)//如果度数为1的点的数目为4,则必为2,3-dimethylbutane
 {
  cout<<"2,3-dimethylbutane"<<'\n';
  return;
 }
 
 count1=0;
 for(int i=1;i<7;i++)//到这一步,只可能是3-methylpentane和2-methylpentane两种,此时,根据度数为1的点是数目来判断
 {
  if(table[count3][i]==1&&flag[i]==1)
  {
   count1++;
  }
 }
 if(count1==1)
 {
  cout<<"3-methylpentane"<<'\n';
 }
 else
 {
  cout<<"2-methylpentane"<<'\n';
 }

以下是完整代码:

#include<iostream>
using namespace std;
class queue{
 private:
  int first,last;
  int *q;
 public:
  queue()
  {
   q=new int[7];
   first=last=0;
  }
  int front()
  {
   return q[first];
  }
  void pop()
  {
   first++;
  }
  void push(int x)
  {
   q[last++]=x;
  }
  bool empty()
  {
   return last==first;
  }
};
int table[7][7];
int reach[7];
int flag[7];
void init()
{
 for(int i=0;i<7;i++)//初始化 
 {
  reach[i]=0;
  flag[i]=0;
  for(int j=0;j<7;j++)
  {
   table[i][j]=0;
  }
 }
}
void bfs(int a)
{
 queue q;
 reach[a]=1;
 q.push(a);
 while(!q.empty())
 {
  int b=q.front();
  q.pop();
  
  for(int i=1;i<7;i++)
  {
   if(table[i][b]==1)
   if(reach[i]==0)
   {
    flag[b]++;
    flag[i]++;
    reach[i]=1;
    q.push(i); 
   }
  }
 }
 int count2=0,count3=0,count1=0;
 for(int i=1;i<7;i++)
 {
  if(flag[i]==4)
  {
   cout<<"2,2-dimethylbutane"<<'\n';
   return;
  }
  else if(flag[i]==2)
  {
   count2++;
  }
  else if(flag[i]==3)
  {
   count3=i;
  }
  else if(flag[i]==1)
  {
   count1++;
  }
 }
  if(count2==4)
 {
  cout<<"n-hexane"<<'\n';
  return;
 }
 if(count1==4)
 {
  cout<<"2,3-dimethylbutane"<<'\n';
  return;
 }
 
 count1=0;
 for(int i=1;i<7;i++)
 {
  if(table[count3][i]==1&&flag[i]==1)
  {
   count1++;
  }
 }
 if(count1==1)
 {
  cout<<"3-methylpentane"<<'\n';
 }
 else
 {
  cout<<"2-methylpentane"<<'\n';
 }
}
int main()
{
 int a,b;
 int n;
 cin>>n;
 for(int i=0;i<n;i++)
 {
  init();
  for(int j=0;j<5;j++)
  {
   cin>>a>>b;
   table[a][b]=table[b][a]=1;
  }
  bfs(a);
 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值