题目描述
小伍开了一个网吧,机房里有若干台电脑,其中有一些电脑已经相互连接。如果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为输入结束,不需要处理。
输出
样例输入
<span style="color:#333333"><span style="color:#333333">4 2
1 2
2 3
0 0
</span></span>
样例输出
<span style="color:#333333"><span style="color:#333333">2
1 2 3
4 </span></span>
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];
}
}
}