判断两点之间是否存在路径 PTA (JAVA)

本题要求输出两个顶点之间是否存在路径

输入格式:

输入包括两部分,第一部分是邻接矩阵表示方法中对应1的两个顶点,用0 0 表示结束
第二部分是两个顶点,例如 Vi和Vj

输出格式:

如果Vi和Vj存在路径,输出1;否则输出0

输入样例:

0 1
1 0
0 4
4 0
1 4
4 1
1 2
2 1
1 3
3 1
2 3
3 2
4 5
5 4
4 6
6 4
0 0
0 5

输出样例:

1

解题思路:本题思路主要是将这些输入数据存入邻接表(自己实现)里,然后通过比较此路径是否在广度优先序列内即可。理论成立,代码如下:

import java.util.*;
public class Main{
public static void main(String[] args){
 Scanner sc=new Scanner(System.in);
   String s="";
   mychart s1=new mychart();
   int c=0,d=0;
   Nodemember t=null;
   while(!(s=sc.nextLine()).equals("0 0"))
   {
	    c=s.charAt(0)-'0';
	    d=s.charAt(2)-'0';
	    //直接头插法
	    t=new Nodemember(d);
	    t.next=s1.a[c].nextone;
	    s1.a[c].nextone=t;
   }
   String s2=sc.nextLine();
   c=s2.charAt(0)-'0';
   d=s2.charAt(2)-'0';
   boolean x=s1.contains(s1, c, d);
   System.out.println(x==true?1:0);
	}
}
class mychart
{
 int visit[];//访问数组
 Nodehead a[];//头节点数组
 mychart()
  {
	visit=new int[100];
	a=new Nodehead[100];
	for(int i=0;i<100;i++)
	a[i]=new Nodehead();	
  } 
 public boolean contains(mychart s1,int v,int b)//灵感来源于数据结构书,邻接表的广度优先遍历。
 {
   Nodemember t;
   int w;
   Queue<Integer> qu =new LinkedList<Integer>();
  	 qu.offer(v);
  	 if(v==b)
  	 return true;
  	 visit[v]=1;
  	while(!qu.isEmpty())
  	{
  	  v=qu.poll();
  	  t=s1.a[v].nextone;
  	  while(t!=null)
  	   {
  		w=t.data;
  		if(visit[w]==0)
  		 {
  		  if(w==b)
  		  return true;
  		  visit[w]=1;
  		  qu.offer(w);
  		 }
  	  t=t.next;
  		}
  	}
  	return false;
 } 
}
class Nodehead//头节点类
{
 char b;
 Nodemember nextone;
 Nodehead()
 {
	nextone=null;
 }
}
class Nodemember//成员节点类
{
 int data;
 Nodemember next;
 Nodemember(int b)
 {
	 this.data=b;
	 this.next=null; 
 }
}

(由于我做这个题的时候只有一个测试点所以输出1或者0试一试就知道了,以后测试点个数会不会变动就不知道了。)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于使用并查集判断两个顶点是否连通的问题,我们可以用并查集来实现。具体实现方法如下: 1. 初始化并查集,每个顶点都是一个单独的集合。 2. 对于每条边 (u, v),将顶点 u 和顶点 v 所在的集合合并。 3. 对于查询操作,判断两个顶点 x 和 y 是否连通,只需要判断它们所在的集合是否相同即可。 实现过程中,可以使用一个数组 parent[] 来表示每个节点的父节点,初始时每个节点的父节点都是它本身。当合并两个集合时,只需要将其中一个集合的根节点的父节点指向另一个集合的根节点即可。判断两个顶点是否连通时,只需要判断它们所在的集合的根节点是否相同即可。 代码示例: ```c++ #include <iostream> #include <cstdio> using namespace std; const int MAXN = 100005; int parent[MAXN]; int find(int x) { if (parent[x] == x) { return x; } parent[x] = find(parent[x]); // 路径压缩 return parent[x]; } void merge(int x, int y) { int root_x = find(x); int root_y = find(y); if (root_x != root_y) { parent[root_x] = root_y; // 将 root_x 的父节点指向 root_y } } bool isConnected(int x, int y) { int root_x = find(x); int root_y = find(y); return root_x == root_y; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { parent[i] = i; // 初始化,每个点的父节点都是它本身 } for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); merge(u, v); // 合并 u 和 v 所在的集合 } int q; scanf("%d", &q); for (int i = 0; i < q; i++) { int x, y; scanf("%d%d", &x, &y); if (isConnected(x, y)) { printf("yes\n"); } else { printf("no\n"); } } return 0; } ``` 以上就是使用并查集判断两个顶点是否连通的方法,希望能够解决你的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值