并查集-检查网络

【问题描述】

给定一个计算机网络以及机器间的双向连线列表,每一条连线允许两端的计算机进行直接的文件传输,其他计算机间若存在一条连通路径,也可以进行间接的文件传输。请写出程序判断:任意指定两台计算机,它们之间是否可以进行文件传输?

【输入要求】

输入若干测试数据组成。对于每一组测试,第1行包含一个整数N(≤10000),即网络中计算机的总台数,因而每台计算机可用1到N之间的一个正整数表示。接下来的几行输入格式为I C1 C2或者 C或者C C1C2或者S,其中C1和C2是两台计算机的序号,I表示在C1和C2间输入一条连线,C表示检查C1和C2间是否可以传输文件,S表示该组测试结束。当N为0时,表示全部测试结束,不要对该数据做任何处理。

【输出要求】

对每一组C开头的测试,检查C1和C2间是否可以传输文件,若可以,则在一行中输出“yes”,否则输出“no”。当读到S时,检查整个网络。若网络中任意两机器间都可以传输文件,则在一行中输出“The network is connected.”,否则输出“There are k components.”,其中k是网络中连通集的个数。两组测试数据之间请输出一空行分隔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <iostream>
using namespace std;
#define MAX_N 10001
 
int par[MAX_N];     // 父亲
int rank[MAX_N];    // 树的高度
 
// 初始化n个元素
void init(int n)
{
    for(int i = 1; i <= n; ++ i)
    {
        par[i] = i;
        rank[i] = 0;
    }
}
 
// 查询树的根
int find(int x)
{
    if(par[x] == x)
        return x;
    else
        return par[x] = find(par[x]);
         
}
 
// 合并x和y所属的集合
void unite(int x, int y)
{
    x = find(x);
    y = find(y);
    if(x == y)
        return ;
     
    if(rank[x] > rank[y])
    {
        par[y] = x;
    }
    else
    {
        par[x] = y;
        if(rank[x] == rank[y])
        {
            rank[x] ++;
        }
    }
}
 
// 判断x和y是否属于同一个集合
bool same(int x, int y)
{
    return find(x) == find(y);
}
 
int main()
{
    // num 为机器总数, m1, m2 为任意两台机器
    int num, m1, m2;
    // command为指令
    char command;
     
    cout << "请输入机器总数:" << endl;
    while(cin >> num)
    {
        // 当N为0时,表示全部测试结束,不要对该数据做任何处理。
        if(num == 0)
            break;
        if(num < 1 || num > MAX_N)
        {
            cout << "数据越界, 请重新输入" << endl;
            continue;
        }
         
        // 并查集开始
        init(num); 
     
        cout << "请输入指令:" << endl;
        while(cin >> command)
        {  
             
            // 错误指令的处理
            if(command != 'S' && command != 'C' && command != 'I')
            {
                cout << "指令错误, 请重新输入" << endl;
                continue;
            }
             
            // 当读到S时,检查整个网络。
            // 若网络中任意两机器间都可以传输文件,则在一行中输出"The network is connected."
            // 否则输出"There are k components."
            if(command == 'S')
            {
                int count = 0;
                for(int i = 1; i <= num; ++ i)
                {
                    if(par[i] == i)
                        count ++;
                }
                if(count == 1)
                {
                    cout << "The network is connected." << endl;
                }
                else
                {
                    cout << "There are " << count << " components." << endl;
                }
                 
                cout << endl;
                cout << "请输入机器总数:" << endl;
                break;
            }
             
            // 输入两个机器
            // cout << "请输入两个机器编号:" << endl;
            cin >> m1 >> m2;
             
            // C开头的测试,检查C1和C2间是否可以传输文件
            // 若可以,则在一行中输出"yes",否则输出"no"。
            if(command == 'C')
            {
                if(same(m1, m2))
                {
                    cout << "yes" << endl;
                }
                else
                {
                    cout << "no" << endl;
                }
                 
                cout << "请输入指令:" << endl;
            }
             
            // I表示在C1和C2间输入一条连线
            if(command == 'I')
            {
                unite(m1, m2);
                 
                cout << "请输入指令:" << endl;
            }
        }
    }
     
    return 0;
}
 
/*
请输入机器总数:
3
请输入指令:
I 3 1
请输入指令:
I 2 3
请输入指令:
C 1 2
yes
请输入指令:
S
The network is connected.
 
请输入机器总数:
3
请输入指令:
C 1 2
no
请输入指令:
I 1 2
请输入指令:
C 1 2
yes
请输入指令:
S
There are 2 components.
*/

  

posted @   青衫客36  阅读(353)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示