小伍开了一个网吧,机房里有若干台电脑,其中有一些电脑已经相互连接。如果A和B通过网线相连,并且B与C也通过网线相连,那么即便A和C之间没有直接的网线相连,也可以认为A和C是相连的(即A,B,C为一组电脑)。由于机房里的布线比较乱,并不是所有电脑都相互连通,
多组数据。每组数据第一行为整数N,M。N是电脑数量,M是机房已布置好的网线数量。接下来M行,每行为整数A,B。表明A,B之间通过一条网线直接相连。这里可以认为网线是不分方向的,即A->B等价于B->A。 (0 < N <= 200,0 <= M <= 10000,0 < A,B <= N 。) N=0和M=0为输入结束,不需要处理。
import java.util.*;
public class Main { static Scanner cin = new Scanner(System.in); static int n,m; public static void main(String[] args) { while(cin.hasNext()) { n = cin.nextInt(); m = cin.nextInt(); if(n==0&&m==0) break; Graph G = new Graph(); CC cc = new CC(G); System.out.println(cc.getCount()); List<Integer>[] list = new LinkedList[cc.getCount()]; for (int i = 0; i < cc.getCount(); i++) { list[i] = new LinkedList<>(); } for (int i = 1; i <= n; i++) { list[cc.id(i)].add(i); } for (int i = 0; i < cc.getCount(); i++) { for(Integer v:list[i]){ System.out.print(v+" "); } System.out.println(); } }
cin.close(); } private static class Graph { static List []adj; public Graph() { adj=new LinkedList[n+1]; for(int i=1;i<=n;i++){ adj[i]=new LinkedList<>(); } for(int i=0;i<m;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]; }
} private static class CC { private boolean []marked; private int []id; private int count; public CC(Graph G) { marked=new boolean[n+1]; id=new int[n+1]; for(int i=1;i<n+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; } public int id(int v){ return id[v]; } } }