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?
Input Specification:
Each input file contains one test case. For each test case, the first line contains N (2≤N≤1e4), 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.
Output Specification:
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.
Sample Input 1:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
Sample Output 1:
no
no
yes
There are 2 components.
Sample Input 2:
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
Sample Output 2:
no
no
yes
yes
The network is connected.
普通并查集:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
int n;
int f[10004]={0};
int getFather(int n)
{
while(f[n] != n)
{
n = f[n];
}
return n;
}
int main()
{
// system("chcp 65001");
cin.tie(0);
cout.tie(0);
// freopen("C:/Users/zhaochen/Desktop/input.txt", "r", stdin);
cin>>n;
for(int i=1;i<=n;i++)
{
f[i]=i; // 初始化并查集
}
char oper;
while(cin>>oper)
{
if(oper == 'S')
break;
int a,b;
cin>>a>>b;
int x=getFather(a);
int y=getFather(b);
if(oper == 'I')
{
f[x] = y; // 把a所在的集合并到b所在的集合里
}
else if(oper == 'C')
{
if(x == y)
{
cout<< "yes"<< endl;
}
else
{
cout<< "no"<< endl;
}
}
}
unordered_set<int>s;
for(int i=1;i<=n;i++)
{
int x = getFather(i);
if(s.find(x) == s.end())
{
s.insert(x);
}
}
if(s.size() == 1)
cout<< "The network is connected.";
else
printf("There are %d components.",s.size());
return 0;
}
Merge优化,按规模归并:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
int n;
int f[10004]= {0};
int getFather(int n)
{
while(f[n] > 0)
{
n = f[n];
}
return n;
}
void Merge(int x,int y) // 合并集合x,y
{
if(x != y)
{
if(f[x] > f[y]) // x的规模比y小
{
f[y] += f[x]; // y的规模增加
f[x] = y;
}
else
{
f[x] += f[y];
f[y] = x;
}
}
}
int main()
{
// system("chcp 65001");
cin.tie(0);
cout.tie(0);
// freopen("C:/Users/zhaochen/Desktop/input.txt", "r", stdin);
cin>>n;
for(int i=1; i<=n; i++)
{
f[i] = -1; // 集合代表人的父结点为负数,绝对值代表集合规模
}
char oper;
while(cin>>oper)
{
if(oper == 'S')
break;
int a,b;
cin>>a>>b;
int x=getFather(a);
int y=getFather(b);
if(oper == 'I')
{
Merge(x,y);
}
else if(oper == 'C')
{
if(x == y)
{
cout<< "yes"<< endl;
}
else
{
cout<< "no"<< endl;
}
}
}
int cnt=0;
for(int i=1; i<=n; i++)
{
if(f[i] < 0) // 找集合代表人
{
cnt++;
}
}
if(cnt == 1)
cout<< "The network is connected.";
else
printf("There are %d components.",cnt);
return 0;
}
getFather优化,路径压缩:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
int n;
int f[10004]= {0};
int getFather(int n)
{
if(f[n] < 0)
{
return n;
}
f[n] = getFather(f[n]);
return f[n];
}
void Merge(int x,int y) // 合并集合x,y
{
if(x != y)
{
if(f[x] > f[y]) // x的规模比y小
{
f[y] += f[x]; // y的规模增加
f[x] = y;
}
else
{
f[x] += f[y];
f[y] = x;
}
}
}
int main()
{
// system("chcp 65001");
cin.tie(0);
cout.tie(0);
// freopen("C:/Users/zhaochen/Desktop/input.txt", "r", stdin);
cin>>n;
for(int i=1; i<=n; i++)
{
f[i] = -1; // 集合代表人的父结点为负数,绝对值代表集合规模
}
char oper;
while(cin>>oper)
{
if(oper == 'S')
break;
int a,b;
cin>>a>>b;
int x=getFather(a);
int y=getFather(b);
if(oper == 'I')
{
Merge(x,y);
}
else if(oper == 'C')
{
if(x == y)
{
cout<< "yes"<< endl;
}
else
{
cout<< "no"<< endl;
}
}
}
int cnt=0;
for(int i=1; i<=n; i++)
{
if(f[i] < 0) // 找集合代表人
{
cnt++;
}
}
if(cnt == 1)
cout<< "The network is connected.";
else
printf("There are %d components.",cnt);
return 0;
}