标签:
题目:http://pta.patest.cn/pta/test/16/exam/4/question/670
PTA - Data Structures and Algorithms (English) - 5-8
We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to any other?
Each input file contains one test case. For each test case, the first line contains N (2≤N≤10?4??), the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and N. Then in the following lines, the input is given in the format:
I c1 c2
where I
stands for inputting a connection between c1
and c2
; or
C c1 c2
where C
stands for checking if it is possible to transfer files between c1
and c2
; or
S
where S
stands for stopping this case.
For each C
case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1
and c2
, respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are k
components." where k
is the number of connected components in this network.
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
no
no
yes
There are 2 components.
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S
no
no
yes
yes
The network is connected
解法转自:http://www.cnblogs.com/clevercong/p/4192953.html
题目分析:
首先输入的是一个整型数,代表网络中有多少个computer(结点)。
然后输入若干行,每行由1个字符,两个整数组成。I 代表增加连接,C 代表检查是否连接,S 代表结束输入。
C 检查连接的时候,要输出yes或者no说明是否连通。
最后输出整个网络的情况,如果全部连通则输出The network is connected.,否则输出有多少个连通分量。
算法示例:
注:左图中 1. 2. 3. 4. 5. 即中间图中的对应操作的结果
1.初始化
int *S; //全局变量定义 // 在main函数中动态申请S S = new int[num+1]; //num+1方便从1开始查起 for(int i=0; i<=num; i++) S[i] = i; //数组下标即Data,数组值为Parent
2.“I”和“C”操作
if(choose == ‘I‘) Union(c1, c2); if(choose == ‘C‘) { if(Find(c1) == Find(c2)) //根相同,即在一个集合中 cout << "yes" << endl; else cout << "no" << endl; }
3.查
int Find( ElementType X ) //找X所在集合的根结点 { if(S[X]==X) return X; return S[X]=Find(S[X]); //向上一直找根,把根赋给S[X]即把结点直接连到根上,使当前树高化为1 }
4.并
void Union( ElementType X1, ElementType X2) //把X1和X2合并到一个并查集中(增加连接) { int Root1, Root2; Root1 = Find(X1); Root2 = Find(X2); if ( Root1 != Root2 ) //!根不相等时才合并 { //!数字大的连到小的上面去 if(S[Root1] < S[Root2]) S[Root2] = Root1; else S[Root1] = Root2; } }
5.求连通分量个数
for(int i=1; i<=num; i++) { if(S[i] == i) //如果Parent就是Data它自己,即为根结点 icount++; }
#include <iostream> using namespace std; int *S; //!找x所在集合的根结点 int Find( int X ) { if(S[X]==X) return X; return S[X]=Find(S[X]); //!向上一直找根,同时把当前结点直接连到根,树的高度化为1 } void Union( int X1, int X2) { int Root1, Root2; Root1 = Find(X1); Root2 = Find(X2); if ( Root1 != Root2 ) //!根不相等时才合并 { //!数字大的连到小的上面去 if(S[Root1] < S[Root2]) S[Root2] = Root1; else S[Root1] = Root2; } } int main() { int num; cin >> num; char choose; int c1, c2; S = new int[num+1]; //!从1开始,方便查找,so一共num+1 //!初始化:数组角标即Data,值为Parent for(int i=0; i<=num; i++) S[i] = i; while(1) { cin >> choose; if(choose == ‘S‘) break; cin >> c1 >> c2; if(choose == ‘I‘) Union(c1, c2); if(choose == ‘C‘) { if(Find(c1) == Find(c2)) cout << "yes" << endl; else cout << "no" << endl; } } int icount=0; //记录有多少个连通分量 for(int i=1; i<=num; i++) { if(S[i] == i) //!如果Parent就Data它自己,证明是根结点 icount++; } if(icount == 1) cout << "The network is connected." << endl; else cout << "There are " << icount << " components." << endl; return 0; }
PTA 5-8(English) File Transfer (25) - 并查集 - 数组实现
标签:
原文地址:http://www.cnblogs.com/claremore/p/4811714.html