2112: 连通图

题目描述

给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。

输入

每组数据的第一行是两个整数 n 和 m(0<=n<=1000)。n 表示图的顶点数目,m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据,每行有两个值 x 和 y(0<x, y <=n),表示顶点 x 和 y 相连,顶点的编号从 1 开始计算。输入不保证这些边是否重复。

输出

对于每组输入数据,如果所有顶点都是连通的,输出"YES",否则输出"NO"。

样例输入

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

样例输出

YES
YES
NO

代码

1.floyd()算法求解 各个点的最短距离矩阵 除行和列相等外 所有的值不为INF 说明图中所有的点都是连通的

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Main {
    static int INF=Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
            int n=cin.nextInt();
            int m=cin.nextInt();
            if(n==0&&m==0) break;
            int edge[][]=new int[n+1][n+1];
            boolean flag=true;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(i==j){
                        edge[i][j]=0;
                    }
                    else {
                        edge[i][j] = INF;
                    }
                }
            }
            for(int i=1;i<=m;i++){
                int x=cin.nextInt();
                int y=cin.nextInt();
                edge[x][y]=1;
                edge[y][x]=1;
            }
            for(int k=1;k<=n;k++){
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++){
                        if(edge[i][k]!=INF&&edge[k][j]!=INF&&edge[i][j]>edge[i][k]+edge[k][j]){
                            edge[i][j]=edge[i][k]+edge[k][j];
                        }
                    }
                }
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(i!=j&&edge[i][j]==INF){
                        flag=false;
                        break;
                    }
                }
            }
            if(flag){
                System.out.println("YES");
            }
            else{
                System.out.println("NO");
            }
        }
        cin.close();
    }
}

2.所有点都是连通的 所以连通分量等于1

第一种方法
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
    static int n;
    static int F[];
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
            n = cin.nextInt();
            int m = cin.nextInt();
            if (n == 0 && m == 0) break;
            init();
            while (m-- > 0) {
                int a = cin.nextInt();
                int b = cin.nextInt();
                union(a, b);
            }
            if (count() == 1) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }

        cin.close();
    }

    private static int count() {
        int count=0;
        for(int i=1;i<F.length;i++){
            if(i==F[i])
                count++;
        }
        return count;
    }

    private static boolean union(int a, int b) {
        int fx=find(a);
        int fy=find(b);
        if(fx==fy){
            return false;
        }
        F[fx]=fy;
        return true;
    }

    private static int find(int a) {
        return a==F[a]? a:(F[a]=find(F[a]));
    }

    private static void init() {
        F=new int[n+1];
        for(int i=1;i<F.length;i++){
            F[i]=i;
        }
    }

}
第二种方法

import java.util.*;
public class Main {
    static int n;
    static int m;
    static Scanner cin=new Scanner(System.in);
    public static void main(String[] args) {
        n=cin.nextInt();
        m=cin.nextInt();
        Graph G=new Graph();
        CC cc=new CC(G);
        if (cc.getCount() == 1) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
        cin.close();
    }
    private static class Graph {
        static int V;
        int E;
        static LinkedList<Integer>[] adj;
        public Graph() {
            this.V=n;
            this.E=m;
            adj=new LinkedList[V+1];
            for(int v=1;v<V+1;v++){
                adj[v]=new LinkedList<>();
            }
            for(int i=0;i<E;i++){
                int v=cin.nextInt();
                int w=cin.nextInt();
                addEdge(v,w);
            }
        }
        private void addEdge(int v, int w) {
            adj[v].add(w);
            adj[w].add(v);
        }
        public Iterable<Integer> adj(int v){
            return adj[v];
        }
        public int V(){
            return V;
        }
    }
    private static class CC {
        private boolean []marked;
        private int []id;
        private int count;
        public CC(Graph G) {
            marked=new boolean[G.V()+1];
            id=new int[G.V()+1];
            for(int i=1;i<G.V()+1;i++){
                if(!marked[i]){
                    dfs(G,i);
                    count++;
                }
            }
        }
        private void dfs(Graph G, int i) {
            marked[i]=true;
            id[i]=count;
            for(int w:G.adj(i)){
                if(!marked[w]){
                    dfs(G,w);
                }
            }
        }
        public int getCount() {
            return count;
        }
    }
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值