并查集 File Transfer
来源:互联网 发布:大数据视频 百度云盘 编辑:程序博客网 时间:2024/05/30 12:30
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≤104), 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:
5C 3 2I 3 2C 1 5I 4 5I 2 4C 3 5S
Sample Output 1:
nonoyesThere are 2 components.
Sample Input 2:
5C 3 2I 3 2C 1 5I 4 5I 2 4C 3 5I 1 3C 1 5S
Sample Output 2:
nonoyesyesThe network is connected.
思路:经典的并查集,但是需要进行优化才能AC
1. 未优化版
#include <iostream>using namespace std;int adj[10002];int myfind(int i) { while(adj[i] != 0) i = adj[i]; return i;}void myunion(int i, int j) { int f1 = myfind(i); int f2 = myfind(j); if(adj[f2] > adj[f1]) adj[f1] = f2;}int main(){ int n; cin >> n; while(true) { char c; cin >> c; if(c == 'S') break; int i, j; cin >>i >> j; if(c == 'I') { myunion(i, j); } else { int f1 = myfind(i); int f2 = myfind(j); if(f1 == f2) cout << "yes" << endl; else cout << "no" << endl; } } int cnt = 0; for(int i=1; i<=n; i++) if(adj[i] == 0)cnt ++; if(cnt == 1) cout << "The network is connected." << endl; else cout << "There are " << cnt << " components." << endl; return 0;}
2. 优化版
#include <iostream>using namespace std;int adj[10002];// 路径压缩,用g++编译器报 段错误 好像没有对尾递归进行优化int myfind(int i) {// if(adj[i] < 0)// return i;// else// return adj[i] = myfind(adj[i]); while(adj[i] > 0) i = adj[i]; return i;}void myunion(int i, int j) { int f1 = myfind(i); int f2 = myfind(j); // 这里用的是按规模归并,每次归并都要注意更新规模 // 更新规模要在归并前!!// if(adj[f2] < adj[f1]) {// adj[f2] += adj[f1];// adj[f1] = f2;// } else {// adj[f1] += adj[f2];// adj[f2] = f1;// } // 按高度归并 if(adj[f1] < adj[f2]) adj[f2] = f1; else { if(adj[f1] == adj[f2]) // 只有当树一样高的时候,才要树高加1 adj[f2]--; adj[f1] = f2; }}// 考察优化:// 1. 按秩归并:按高度或者按规模选择谁加到谁// 2. 路径压缩:每次find了自后,都把遍历过的节点的adj都更新为最顶端的父节点int main(){ int n; cin >> n; while(true) { char c; cin >> c; if(c == 'S') break; int i, j; cin >>i >> j; if(c == 'I') { myunion(i, j); } else { int f1 = myfind(i); int f2 = myfind(j); if(f1 == f2) cout << "yes" << endl; else cout << "no" << endl; } } int cnt = 0; for(int i=1; i<=n; i++) if(adj[i] <= 0)cnt ++; if(cnt == 1) cout << "The network is connected." << endl; else cout << "There are " << cnt << " components." << endl; return 0;}
- 并查集 File Transfer
- PAT File Transfer(并查集)
- 04-2. File Transfer (25)并查集
- PAT 04-2. File Transfer (25) (并查集)
- PAT 04-2. File Transfer (并查集) (Java实现)
- file transfer(文档传送程序)-并查集的应用
- 05-树8 File Transfer【并查集】
- 并查集-05-树8 File Transfer
- 05-树8 File Transfer (25分)---并查集
- 5-8 File Transfer (25分) (简单的并查集, 注意getchar())
- File Transfer
- File Transfer
- File Transfer
- File Transfer
- File Transfer
- RFC959 - File Transfer Protocol
- Android file transfer/Upload
- FTP, File Transfer Protocol
- BCH and Hamming Codes
- (一)深入数组--内存中的数组
- 列表初始化
- mac终端切换用户
- python string 转dict
- 并查集 File Transfer
- c++第四次作业
- java调用python函数
- JSP
- SpannableString与SpannableStringBuilder使用
- verilog代码编写风格(他人整理)
- 红米4的手机被我刷的基带丢失
- Docker入门记录 [1]
- 综教楼后的那个坑