“美登杯”上海市高校大学生程序设计 C. 小花梨判连通 (并查集+map)
Problem C C 、 小 花梨 判連通
時間限制:2000ms 空間限制:512MB
Description
小花梨給出?個點,讓?位同學(xué)對這?個點任意添加無向邊,構(gòu)成?張圖。小花梨想知道對于
每個點?,存在多少個點?(包括?本身),使得?和?在這?張圖中都是連通的。
Input
第一行輸入兩個正整數(shù)?和?,分別表示點的個數(shù)和同學(xué)數(shù)。
接下來分成?部分進行輸入,每部分輸入格式相同。
每部分第一行輸入一個整數(shù)??,表示第?位同學(xué)連邊的數(shù)目。
接下來??行,每行兩個正整數(shù)?,?,表示第?位同學(xué)將點?和點?之間進行連接。
可能會存在重邊或者自環(huán)。
(1 ≤ ? ≤ 100000,1 ≤ ? ≤ 10,1 ≤ ?,? ≤ ?,0 ≤ ?? ≤ 200000)
Output
輸出?行,第?行輸出在?張圖中都和編號為?的點連通的點的數(shù)目(包括?本身)
Example
Sample Input Sample Output
4 2
3
1 2
1 3
2 3
2
1 2
3 4
2
2
1
1
思路:
· 我們?nèi)绻鶕?jù)圖中每一條邊進行并查集的merge,那么在一張圖中,如果兩個節(jié)點聯(lián)通,那么他們的祖先一定相等。
那么我們對每一個節(jié)點創(chuàng)建一個vector,來依次存它在k張圖中的祖先。
那么我們可以知道 如果兩個節(jié)點在k張圖中都聯(lián)通,那么它們的vector數(shù)組是相等的。
然后我們不妨使用map對vector 出現(xiàn)的次數(shù)進行統(tǒng)計,從而可以得出答案。
細節(jié)見代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl using namespace std; typedef long long ll; ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;} ll lcm(ll a, ll b) {return a / gcd(a, b) * b;} ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;} inline void getInt(int *p); const int maxn = 100010; const int inf = 0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ int far[maxn]; int n; void init() {repd(i, 1, n) {far[i] = i;} } int findpar(int x) {if (x == far[x]) {return x;} else {return far[x] = findpar(far[x]);} }void merge_(int x, int y) {x = findpar(x);y = findpar(y);if (x != y) {far[x] = y;} }int k; std::vector<int> v[maxn]; map<vector<int>, int> vis;int main() {//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);gbtb;cin >> n >> k;int num;while (k--) {init();cin >> num;repd(i, 1, num) {int x, y;cin >> x >> y;merge_(x, y);}repd(i, 1, n) {v[i].push_back(findpar(i));}}// repd(i, 1, n) {// for (auto x : v[i]) {// cout << x << " ";// }// cout << endl;// }repd(i, 1, n) {vis[v[i]]++;}repd(i, 1, n) {cout << vis[v[i]] << endl;}return 0; }inline void getInt(int *p) {char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}} else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}} }轉(zhuǎn)載于:https://www.cnblogs.com/qieqiemin/p/11491137.html
總結(jié)
以上是生活随笔為你收集整理的“美登杯”上海市高校大学生程序设计 C. 小花梨判连通 (并查集+map)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Advapi 登录类型8的错误
- 下一篇: 推荐系列文章:《DotText源码阅读》